mirror of
https://github.com/uprightbass360/AzerothCore-RealmMaster.git
synced 2026-01-13 00:58:34 +00:00
new repo and uid features
This commit is contained in:
@@ -48,12 +48,12 @@ AC_DB_IMPORT_IMAGE=acore/ac-wotlk-db-import:14.0.0-dev
|
|||||||
AC_AUTHSERVER_IMAGE=acore/ac-wotlk-authserver:14.0.0-dev
|
AC_AUTHSERVER_IMAGE=acore/ac-wotlk-authserver:14.0.0-dev
|
||||||
AC_WORLDSERVER_IMAGE=acore/ac-wotlk-worldserver:14.0.0-dev
|
AC_WORLDSERVER_IMAGE=acore/ac-wotlk-worldserver:14.0.0-dev
|
||||||
# Services (Playerbots)
|
# Services (Playerbots)
|
||||||
AC_AUTHSERVER_IMAGE_PLAYERBOTS=acore/ac-wotlk-authserver:master
|
AC_AUTHSERVER_IMAGE_PLAYERBOTS=acore-compose:authserver-playerbots
|
||||||
AC_WORLDSERVER_IMAGE_PLAYERBOTS=acore/ac-wotlk-worldserver:master
|
AC_WORLDSERVER_IMAGE_PLAYERBOTS=acore-compose:worldserver-playerbots
|
||||||
# Services (Module Build Tags)
|
# Services (Module Build Tags)
|
||||||
# Images used during module compilation and tagging
|
# Images used during module compilation and tagging
|
||||||
AC_AUTHSERVER_IMAGE_MODULES=acore/ac-wotlk-authserver:modules-latest
|
AC_AUTHSERVER_IMAGE_MODULES=acore-compose:authserver-modules-latest
|
||||||
AC_WORLDSERVER_IMAGE_MODULES=acore/ac-wotlk-worldserver:modules-latest
|
AC_WORLDSERVER_IMAGE_MODULES=acore-compose:worldserver-modules-latest
|
||||||
# Client Data
|
# Client Data
|
||||||
AC_CLIENT_DATA_IMAGE=acore/ac-wotlk-client-data:14.0.0-dev
|
AC_CLIENT_DATA_IMAGE=acore/ac-wotlk-client-data:14.0.0-dev
|
||||||
AC_CLIENT_DATA_IMAGE_PLAYERBOTS=uprightbass360/azerothcore-wotlk-playerbots:client-data-Playerbot
|
AC_CLIENT_DATA_IMAGE_PLAYERBOTS=uprightbass360/azerothcore-wotlk-playerbots:client-data-Playerbot
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ cd acore-compose
|
|||||||
./deploy.sh
|
./deploy.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
> ℹ️ **Image Sources:** Vanilla/standard profiles run the upstream `acore/*` images. As soon as you enable playerbots or any C++ module, the toolchain switches to the `uprightbass360/azerothcore-wotlk-playerbots` fork, rebuilds it locally when needed, and produces fresh `uprightbass360/...:modules-latest` tags.
|
> ℹ️ **Image Sources:** Vanilla/standard profiles run the upstream `acore/*` images. As soon as you enable playerbots or any C++ module, the toolchain compiles locally and retags the results to your compose project name (for example, `acore-compose:authserver-playerbots`, `acore-compose:worldserver-playerbots`, `acore-compose:db-import-playerbots`, `acore-compose:client-data-playerbots`, and `acore-compose:authserver-modules-latest`), keeping everything self-contained.
|
||||||
|
|
||||||
**4. Create Admin Account**
|
**4. Create Admin Account**
|
||||||
|
|
||||||
@@ -83,7 +83,7 @@ set realmlist 203.0.113.100 8215
|
|||||||
### ✅ Core Server Components
|
### ✅ Core Server Components
|
||||||
- **AzerothCore 3.3.5a** - WotLK server application
|
- **AzerothCore 3.3.5a** - WotLK server application
|
||||||
- **MySQL 8.0** - Database with intelligent initialization and restoration
|
- **MySQL 8.0** - Database with intelligent initialization and restoration
|
||||||
- **Smart Module System** - Automated module management and source builds (compiles the uprightbass360 playerbot fork whenever modules need C++ changes)
|
- **Smart Module System** - Automated module management and source builds (compiles the [mod-playerbots fork](https://github.com/mod-playerbots/azerothcore-wotlk/tree/Playerbot) whenever modules need C++ changes)
|
||||||
- **phpMyAdmin** - Web-based database administration
|
- **phpMyAdmin** - Web-based database administration
|
||||||
- **Keira3** - Game content editor and developer tools
|
- **Keira3** - Game content editor and developer tools
|
||||||
|
|
||||||
@@ -219,7 +219,7 @@ ssh docker-server '
|
|||||||
./deploy.sh --yes --no-watch
|
./deploy.sh --yes --no-watch
|
||||||
'
|
'
|
||||||
```
|
```
|
||||||
Because the `.env` now points the modules profile at the `uprightbass360/...:modules-latest` tags, the remote compose run uses the build you just migrated—no additional rebuild required.
|
Because the `.env` now points the modules profile at your project-local tags (for example `acore-compose:authserver-modules-latest`), the remote compose run uses the build you just migrated—no additional rebuild required.
|
||||||
|
|
||||||
4. **Verify**
|
4. **Verify**
|
||||||
```bash
|
```bash
|
||||||
@@ -382,7 +382,7 @@ http://YOUR_SERVER_IP:4201
|
|||||||
|
|
||||||
# Module staging and compilation
|
# Module staging and compilation
|
||||||
./scripts/stage-modules.sh # Download and stage enabled modules (preps upright playerbot builds)
|
./scripts/stage-modules.sh # Download and stage enabled modules (preps upright playerbot builds)
|
||||||
./scripts/rebuild-with-modules.sh --yes # Rebuild uprightbass360/playerbot images with your modules
|
./scripts/rebuild-with-modules.sh --yes # Rebuild mod-playerbots images with your modules
|
||||||
./scripts/setup-source.sh # Initialize/update source repositories (auto-switches to playerbot fork for modules)
|
./scripts/setup-source.sh # Initialize/update source repositories (auto-switches to playerbot fork for modules)
|
||||||
|
|
||||||
# Module configuration management
|
# Module configuration management
|
||||||
|
|||||||
84
build.sh
84
build.sh
@@ -81,6 +81,20 @@ read_env(){
|
|||||||
echo "$value"
|
echo "$value"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
update_env_value(){
|
||||||
|
local key="$1" value="$2" env_file="$ENV_PATH"
|
||||||
|
[ -n "$env_file" ] || return 0
|
||||||
|
if [ ! -f "$env_file" ]; then
|
||||||
|
printf '%s=%s\n' "$key" "$value" >> "$env_file"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
if grep -q "^${key}=" "$env_file"; then
|
||||||
|
sed -i "s|^${key}=.*|${key}=${value}|" "$env_file"
|
||||||
|
else
|
||||||
|
printf '\n%s=%s\n' "$key" "$value" >> "$env_file"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
MODULE_HELPER="$ROOT_DIR/scripts/modules.py"
|
MODULE_HELPER="$ROOT_DIR/scripts/modules.py"
|
||||||
MODULE_STATE_INITIALIZED=0
|
MODULE_STATE_INITIALIZED=0
|
||||||
declare -a MODULES_COMPILE_LIST=()
|
declare -a MODULES_COMPILE_LIST=()
|
||||||
@@ -99,6 +113,7 @@ generate_module_state(){
|
|||||||
local storage_root
|
local storage_root
|
||||||
storage_root="$(resolve_local_storage_path)"
|
storage_root="$(resolve_local_storage_path)"
|
||||||
local output_dir="${storage_root}/modules"
|
local output_dir="${storage_root}/modules"
|
||||||
|
ensure_modules_dir_writable "$storage_root"
|
||||||
if ! python3 "$MODULE_HELPER" --env-path "$ENV_PATH" --manifest "$ROOT_DIR/config/modules.json" generate --output-dir "$output_dir"; then
|
if ! python3 "$MODULE_HELPER" --env-path "$ENV_PATH" --manifest "$ROOT_DIR/config/modules.json" generate --output-dir "$output_dir"; then
|
||||||
err "Module manifest validation failed. See errors above."
|
err "Module manifest validation failed. See errors above."
|
||||||
exit 1
|
exit 1
|
||||||
@@ -229,8 +244,8 @@ detect_rebuild_reasons(){
|
|||||||
if [ "$any_cxx_modules" = "1" ]; then
|
if [ "$any_cxx_modules" = "1" ]; then
|
||||||
local authserver_modules_image
|
local authserver_modules_image
|
||||||
local worldserver_modules_image
|
local worldserver_modules_image
|
||||||
authserver_modules_image="$(read_env AC_AUTHSERVER_IMAGE_MODULES "uprightbass360/azerothcore-wotlk-playerbots:authserver-modules-latest")"
|
authserver_modules_image="$(read_env AC_AUTHSERVER_IMAGE_MODULES "$(resolve_project_image "authserver-modules-latest")")"
|
||||||
worldserver_modules_image="$(read_env AC_WORLDSERVER_IMAGE_MODULES "uprightbass360/azerothcore-wotlk-playerbots:worldserver-modules-latest")"
|
worldserver_modules_image="$(read_env AC_WORLDSERVER_IMAGE_MODULES "$(resolve_project_image "worldserver-modules-latest")")"
|
||||||
|
|
||||||
if ! docker image inspect "$authserver_modules_image" >/dev/null 2>&1; then
|
if ! docker image inspect "$authserver_modules_image" >/dev/null 2>&1; then
|
||||||
reasons+=("C++ modules enabled but authserver modules image $authserver_modules_image is missing")
|
reasons+=("C++ modules enabled but authserver modules image $authserver_modules_image is missing")
|
||||||
@@ -336,6 +351,41 @@ resolve_project_name(){
|
|||||||
echo "$sanitized"
|
echo "$sanitized"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ensure_modules_dir_writable(){
|
||||||
|
local base_path="$1"
|
||||||
|
local modules_dir="${base_path%/}/modules"
|
||||||
|
ensure_host_writable "$modules_dir"
|
||||||
|
}
|
||||||
|
|
||||||
|
ensure_host_writable(){
|
||||||
|
local target="$1"
|
||||||
|
[ -n "$target" ] || return 0
|
||||||
|
if [ -d "$target" ] || mkdir -p "$target" 2>/dev/null; then
|
||||||
|
local uid gid
|
||||||
|
uid="$(id -u)"
|
||||||
|
gid="$(id -g)"
|
||||||
|
if ! chown -R "$uid":"$gid" "$target" 2>/dev/null; then
|
||||||
|
if command -v docker >/dev/null 2>&1; then
|
||||||
|
local helper_image
|
||||||
|
helper_image="$(read_env ALPINE_IMAGE "alpine:latest")"
|
||||||
|
docker run --rm \
|
||||||
|
-u 0:0 \
|
||||||
|
-v "$target":/workspace \
|
||||||
|
"$helper_image" \
|
||||||
|
sh -c "chown -R ${uid}:${gid} /workspace" >/dev/null 2>&1 || true
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
chmod -R u+rwX "$target" 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve_project_image(){
|
||||||
|
local tag="$1"
|
||||||
|
local project_name
|
||||||
|
project_name="$(resolve_project_name)"
|
||||||
|
echo "${project_name}:${tag}"
|
||||||
|
}
|
||||||
|
|
||||||
stage_modules(){
|
stage_modules(){
|
||||||
local src_path="$1"
|
local src_path="$1"
|
||||||
local storage_path
|
local storage_path
|
||||||
@@ -355,17 +405,21 @@ stage_modules(){
|
|||||||
|
|
||||||
local local_modules_dir="${src_path}/modules"
|
local local_modules_dir="${src_path}/modules"
|
||||||
mkdir -p "$local_modules_dir"
|
mkdir -p "$local_modules_dir"
|
||||||
|
ensure_host_writable "$local_modules_dir"
|
||||||
|
|
||||||
local staging_modules_dir="${storage_path}/modules"
|
local staging_modules_dir="${storage_path}/modules"
|
||||||
export MODULES_HOST_DIR="$staging_modules_dir"
|
export MODULES_HOST_DIR="$staging_modules_dir"
|
||||||
|
ensure_host_writable "$staging_modules_dir"
|
||||||
|
|
||||||
local env_target_dir="$src_path/env/dist/etc"
|
local env_target_dir="$src_path/env/dist/etc"
|
||||||
mkdir -p "$env_target_dir"
|
mkdir -p "$env_target_dir"
|
||||||
export MODULES_ENV_TARGET_DIR="$env_target_dir"
|
export MODULES_ENV_TARGET_DIR="$env_target_dir"
|
||||||
|
ensure_host_writable "$env_target_dir"
|
||||||
|
|
||||||
local lua_target_dir="$src_path/lua_scripts"
|
local lua_target_dir="$src_path/lua_scripts"
|
||||||
mkdir -p "$lua_target_dir"
|
mkdir -p "$lua_target_dir"
|
||||||
export MODULES_LUA_TARGET_DIR="$lua_target_dir"
|
export MODULES_LUA_TARGET_DIR="$lua_target_dir"
|
||||||
|
ensure_host_writable "$lua_target_dir"
|
||||||
|
|
||||||
# Set up local storage path for build sentinel tracking
|
# Set up local storage path for build sentinel tracking
|
||||||
local local_storage_path
|
local local_storage_path
|
||||||
@@ -475,21 +529,31 @@ tag_module_images(){
|
|||||||
local target_auth
|
local target_auth
|
||||||
local target_world
|
local target_world
|
||||||
|
|
||||||
source_auth="$(read_env AC_AUTHSERVER_IMAGE_PLAYERBOTS "uprightbass360/azerothcore-wotlk-playerbots:authserver-Playerbot")"
|
source_auth="$(read_env AC_AUTHSERVER_IMAGE_PLAYERBOTS "$(resolve_project_image "authserver-playerbots")")"
|
||||||
source_world="$(read_env AC_WORLDSERVER_IMAGE_PLAYERBOTS "uprightbass360/azerothcore-wotlk-playerbots:worldserver-Playerbot")"
|
source_world="$(read_env AC_WORLDSERVER_IMAGE_PLAYERBOTS "$(resolve_project_image "worldserver-playerbots")")"
|
||||||
target_auth="$(read_env AC_AUTHSERVER_IMAGE_MODULES "uprightbass360/azerothcore-wotlk-playerbots:authserver-modules-latest")"
|
target_auth="$(read_env AC_AUTHSERVER_IMAGE_MODULES "$(resolve_project_image "authserver-modules-latest")")"
|
||||||
target_world="$(read_env AC_WORLDSERVER_IMAGE_MODULES "uprightbass360/azerothcore-wotlk-playerbots:worldserver-modules-latest")"
|
target_world="$(read_env AC_WORLDSERVER_IMAGE_MODULES "$(resolve_project_image "worldserver-modules-latest")")"
|
||||||
|
|
||||||
if docker image inspect "$source_auth" >/dev/null 2>&1; then
|
if docker image inspect "$source_auth" >/dev/null 2>&1; then
|
||||||
docker tag "$source_auth" "$target_auth"
|
if docker tag "$source_auth" "$target_auth"; then
|
||||||
ok "Tagged $target_auth from $source_auth"
|
ok "Tagged $target_auth from $source_auth"
|
||||||
|
update_env_value "AC_AUTHSERVER_IMAGE_PLAYERBOTS" "$source_auth"
|
||||||
|
update_env_value "AC_AUTHSERVER_IMAGE_MODULES" "$target_auth"
|
||||||
|
else
|
||||||
|
warn "Failed to tag $target_auth from $source_auth"
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
warn "Source authserver image $source_auth not found; skipping modules tag"
|
warn "Source authserver image $source_auth not found; skipping modules tag"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if docker image inspect "$source_world" >/dev/null 2>&1; then
|
if docker image inspect "$source_world" >/dev/null 2>&1; then
|
||||||
docker tag "$source_world" "$target_world"
|
if docker tag "$source_world" "$target_world"; then
|
||||||
ok "Tagged $target_world from $source_world"
|
ok "Tagged $target_world from $source_world"
|
||||||
|
update_env_value "AC_WORLDSERVER_IMAGE_PLAYERBOTS" "$source_world"
|
||||||
|
update_env_value "AC_WORLDSERVER_IMAGE_MODULES" "$target_world"
|
||||||
|
else
|
||||||
|
warn "Failed to tag $target_world from $source_world"
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
warn "Source worldserver image $source_world not found; skipping modules tag"
|
warn "Source worldserver image $source_world not found; skipping modules tag"
|
||||||
fi
|
fi
|
||||||
|
|||||||
19
cleanup.sh
19
cleanup.sh
@@ -128,6 +128,22 @@ STORAGE_PATH="${STORAGE_PATH:-$STORAGE_PATH_DEFAULT}"
|
|||||||
STORAGE_PATH_LOCAL="${STORAGE_PATH_LOCAL:-$STORAGE_PATH_LOCAL_DEFAULT}"
|
STORAGE_PATH_LOCAL="${STORAGE_PATH_LOCAL:-$STORAGE_PATH_LOCAL_DEFAULT}"
|
||||||
PROJECT_NAME="${COMPOSE_PROJECT_NAME:-ac-compose}"
|
PROJECT_NAME="${COMPOSE_PROJECT_NAME:-ac-compose}"
|
||||||
|
|
||||||
|
sanitize_project_name(){
|
||||||
|
local raw="$1"
|
||||||
|
local sanitized
|
||||||
|
sanitized="$(echo "$raw" | tr '[:upper:]' '[:lower:]')"
|
||||||
|
sanitized="${sanitized// /-}"
|
||||||
|
sanitized="$(echo "$sanitized" | tr -cd 'a-z0-9_-')"
|
||||||
|
if [[ -z "$sanitized" ]]; then
|
||||||
|
sanitized="acore-compose"
|
||||||
|
elif [[ ! "$sanitized" =~ ^[a-z0-9] ]]; then
|
||||||
|
sanitized="ac${sanitized}"
|
||||||
|
fi
|
||||||
|
echo "$sanitized"
|
||||||
|
}
|
||||||
|
|
||||||
|
PROJECT_IMAGE_PREFIX="$(sanitize_project_name "${COMPOSE_PROJECT_NAME:-acore-compose}")"
|
||||||
|
|
||||||
remove_storage_dir(){
|
remove_storage_dir(){
|
||||||
local path="$1"
|
local path="$1"
|
||||||
if [ -d "$path" ]; then
|
if [ -d "$path" ]; then
|
||||||
@@ -203,7 +219,8 @@ nuclear_cleanup() {
|
|||||||
|
|
||||||
# Remove project images (server/tool images typical to this project)
|
# Remove project images (server/tool images typical to this project)
|
||||||
execute_command "Remove acore images" "docker images --format '{{.Repository}}:{{.Tag}}' | grep -E '^acore/' | xargs -r docker rmi"
|
execute_command "Remove acore images" "docker images --format '{{.Repository}}:{{.Tag}}' | grep -E '^acore/' | xargs -r docker rmi"
|
||||||
execute_command "Remove playerbots images" "docker images --format '{{.Repository}}:{{.Tag}}' | grep -E '^uprightbass360/azerothcore-wotlk-playerbots' | xargs -r docker rmi"
|
execute_command "Remove local project images" "docker images --format '{{.Repository}}:{{.Tag}}' | grep -E '^${PROJECT_IMAGE_PREFIX}:' | xargs -r docker rmi"
|
||||||
|
execute_command "Remove legacy playerbots images" "docker images --format '{{.Repository}}:{{.Tag}}' | grep -E '^uprightbass360/azerothcore-wotlk-playerbots' | xargs -r docker rmi"
|
||||||
execute_command "Remove tool images" "docker images --format '{{.Repository}}:{{.Tag}}' | grep -E 'phpmyadmin|uprightbass360/keira3' | xargs -r docker rmi"
|
execute_command "Remove tool images" "docker images --format '{{.Repository}}:{{.Tag}}' | grep -E 'phpmyadmin|uprightbass360/keira3' | xargs -r docker rmi"
|
||||||
|
|
||||||
# Storage cleanup (preserve backups if requested)
|
# Storage cleanup (preserve backups if requested)
|
||||||
|
|||||||
65
deploy.sh
65
deploy.sh
@@ -288,6 +288,28 @@ resolve_local_storage_path(){
|
|||||||
echo "${path%/}"
|
echo "${path%/}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ensure_modules_dir_writable(){
|
||||||
|
local base_path="$1"
|
||||||
|
local modules_dir="${base_path%/}/modules"
|
||||||
|
if [ -d "$modules_dir" ] || mkdir -p "$modules_dir" 2>/dev/null; then
|
||||||
|
local uid gid
|
||||||
|
uid="$(id -u)"
|
||||||
|
gid="$(id -g)"
|
||||||
|
if ! chown -R "$uid":"$gid" "$modules_dir" 2>/dev/null; then
|
||||||
|
if command -v docker >/dev/null 2>&1; then
|
||||||
|
local helper_image
|
||||||
|
helper_image="$(read_env ALPINE_IMAGE "alpine:latest")"
|
||||||
|
docker run --rm \
|
||||||
|
-u 0:0 \
|
||||||
|
-v "$modules_dir":/modules \
|
||||||
|
"$helper_image" \
|
||||||
|
sh -c "chown -R ${uid}:${gid} /modules && chmod -R ug+rwX /modules" >/dev/null 2>&1 || true
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
chmod -R u+rwX "$modules_dir" 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
ensure_module_state(){
|
ensure_module_state(){
|
||||||
if [ "$MODULE_STATE_INITIALIZED" -eq 1 ]; then
|
if [ "$MODULE_STATE_INITIALIZED" -eq 1 ]; then
|
||||||
return
|
return
|
||||||
@@ -296,6 +318,7 @@ ensure_module_state(){
|
|||||||
local storage_root
|
local storage_root
|
||||||
storage_root="$(resolve_local_storage_path)"
|
storage_root="$(resolve_local_storage_path)"
|
||||||
local output_dir="${storage_root}/modules"
|
local output_dir="${storage_root}/modules"
|
||||||
|
ensure_modules_dir_writable "$storage_root"
|
||||||
|
|
||||||
if ! python3 "$MODULE_HELPER" --env-path "$ENV_PATH" --manifest "$ROOT_DIR/config/modules.json" generate --output-dir "$output_dir"; then
|
if ! python3 "$MODULE_HELPER" --env-path "$ENV_PATH" --manifest "$ROOT_DIR/config/modules.json" generate --output-dir "$output_dir"; then
|
||||||
err "Module manifest validation failed. See errors above."
|
err "Module manifest validation failed. See errors above."
|
||||||
@@ -329,6 +352,13 @@ resolve_project_name(){
|
|||||||
echo "$sanitized"
|
echo "$sanitized"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resolve_project_image(){
|
||||||
|
local tag="$1"
|
||||||
|
local project_name
|
||||||
|
project_name="$(resolve_project_name)"
|
||||||
|
echo "${project_name}:${tag}"
|
||||||
|
}
|
||||||
|
|
||||||
filter_empty_lines(){
|
filter_empty_lines(){
|
||||||
awk '
|
awk '
|
||||||
/^[[:space:]]*$/ {
|
/^[[:space:]]*$/ {
|
||||||
@@ -369,8 +399,8 @@ detect_build_needed(){
|
|||||||
if [ "$any_cxx_modules" = "1" ]; then
|
if [ "$any_cxx_modules" = "1" ]; then
|
||||||
local authserver_modules_image
|
local authserver_modules_image
|
||||||
local worldserver_modules_image
|
local worldserver_modules_image
|
||||||
authserver_modules_image="$(read_env AC_AUTHSERVER_IMAGE_MODULES "uprightbass360/azerothcore-wotlk-playerbots:authserver-modules-latest")"
|
authserver_modules_image="$(read_env AC_AUTHSERVER_IMAGE_MODULES "$(resolve_project_image "authserver-modules-latest")")"
|
||||||
worldserver_modules_image="$(read_env AC_WORLDSERVER_IMAGE_MODULES "uprightbass360/azerothcore-wotlk-playerbots:worldserver-modules-latest")"
|
worldserver_modules_image="$(read_env AC_WORLDSERVER_IMAGE_MODULES "$(resolve_project_image "worldserver-modules-latest")")"
|
||||||
|
|
||||||
if ! docker image inspect "$authserver_modules_image" >/dev/null 2>&1; then
|
if ! docker image inspect "$authserver_modules_image" >/dev/null 2>&1; then
|
||||||
reasons+=("C++ modules enabled but authserver modules image $authserver_modules_image is missing")
|
reasons+=("C++ modules enabled but authserver modules image $authserver_modules_image is missing")
|
||||||
@@ -412,7 +442,25 @@ mark_deployment_complete(){
|
|||||||
warn "Cannot create local-storage directory. Deployment tracking may not work properly."
|
warn "Cannot create local-storage directory. Deployment tracking may not work properly."
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
date > "$sentinel"
|
if ! date > "$sentinel" 2>/dev/null; then
|
||||||
|
local sentinel_dir
|
||||||
|
sentinel_dir="$(dirname "$sentinel")"
|
||||||
|
if command -v docker >/dev/null 2>&1; then
|
||||||
|
local helper_image
|
||||||
|
helper_image="$(read_env ALPINE_IMAGE "alpine:latest")"
|
||||||
|
local container_user
|
||||||
|
container_user="$(read_env CONTAINER_USER "$(id -u):$(id -g)")"
|
||||||
|
docker run --rm \
|
||||||
|
--user "$container_user" \
|
||||||
|
-v "$sentinel_dir":/sentinel \
|
||||||
|
"$helper_image" \
|
||||||
|
sh -c 'date > /sentinel/.last_deployed' >/dev/null 2>&1 || true
|
||||||
|
fi
|
||||||
|
if [ ! -f "$sentinel" ]; then
|
||||||
|
warn "Unable to update deployment marker at $sentinel (permission denied)."
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
modules_need_rebuild(){
|
modules_need_rebuild(){
|
||||||
@@ -453,6 +501,17 @@ prompt_build_if_needed(){
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ "$ASSUME_YES" -eq 1 ]; then
|
||||||
|
warn "Build required; auto-confirming (--yes)"
|
||||||
|
if (cd "$ROOT_DIR" && ./build.sh --yes); then
|
||||||
|
ok "Build completed successfully"
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
err "Build failed"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
# Interactive prompt
|
# Interactive prompt
|
||||||
echo
|
echo
|
||||||
warn "Build appears to be required:"
|
warn "Build appears to be required:"
|
||||||
|
|||||||
@@ -18,6 +18,27 @@ ok(){ printf '%b\n' "${GREEN}✅ $*${NC}"; }
|
|||||||
warn(){ printf '%b\n' "${YELLOW}⚠️ $*${NC}"; }
|
warn(){ printf '%b\n' "${YELLOW}⚠️ $*${NC}"; }
|
||||||
err(){ printf '%b\n' "${RED}❌ $*${NC}"; exit 1; }
|
err(){ printf '%b\n' "${RED}❌ $*${NC}"; exit 1; }
|
||||||
|
|
||||||
|
read_env_value(){
|
||||||
|
local key="$1" default="${2:-}" value="${!key:-}"
|
||||||
|
if [ -n "$value" ]; then
|
||||||
|
echo "$value"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
if [ -f "$ENV_PATH" ]; then
|
||||||
|
value="$(grep -E "^${key}=" "$ENV_PATH" 2>/dev/null | tail -n1 | cut -d'=' -f2- | tr -d '\r')"
|
||||||
|
value="$(echo "$value" | sed 's/[[:space:]]*#.*//' | sed 's/[[:space:]]*$//')"
|
||||||
|
if [[ "$value" == \"*\" && "$value" == *\" ]]; then
|
||||||
|
value="${value:1:-1}"
|
||||||
|
elif [[ "$value" == \'*\' && "$value" == *\' ]]; then
|
||||||
|
value="${value:1:-1}"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if [ -z "${value:-}" ]; then
|
||||||
|
value="$default"
|
||||||
|
fi
|
||||||
|
printf '%s\n' "${value}"
|
||||||
|
}
|
||||||
|
|
||||||
ensure_python(){
|
ensure_python(){
|
||||||
if ! command -v python3 >/dev/null 2>&1; then
|
if ! command -v python3 >/dev/null 2>&1; then
|
||||||
err "python3 is required but not installed in PATH"
|
err "python3 is required but not installed in PATH"
|
||||||
@@ -193,11 +214,24 @@ update_playerbots_db_info(){
|
|||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
local host="${CONTAINER_MYSQL:-${MYSQL_HOST:-127.0.0.1}}"
|
local host
|
||||||
local port="${MYSQL_PORT:-3306}"
|
host="$(read_env_value CONTAINER_MYSQL)"
|
||||||
local user="${MYSQL_USER:-root}"
|
if [ -z "$host" ]; then
|
||||||
local pass="${MYSQL_ROOT_PASSWORD:-acore}"
|
host="$(read_env_value MYSQL_HOST)"
|
||||||
local db="${DB_PLAYERBOTS_NAME:-acore_playerbots}"
|
fi
|
||||||
|
host="${host:-ac-mysql}"
|
||||||
|
|
||||||
|
local port
|
||||||
|
port="$(read_env_value MYSQL_PORT "3306")"
|
||||||
|
|
||||||
|
local user
|
||||||
|
user="$(read_env_value MYSQL_USER "root")"
|
||||||
|
|
||||||
|
local pass
|
||||||
|
pass="$(read_env_value MYSQL_ROOT_PASSWORD)"
|
||||||
|
|
||||||
|
local db
|
||||||
|
db="$(read_env_value DB_PLAYERBOTS_NAME "acore_playerbots")"
|
||||||
local value="${host};${port};${user};${pass};${db}"
|
local value="${host};${port};${user};${pass};${db}"
|
||||||
|
|
||||||
if grep -qE '^[[:space:]]*PlayerbotsDatabaseInfo[[:space:]]*=' "$target"; then
|
if grep -qE '^[[:space:]]*PlayerbotsDatabaseInfo[[:space:]]*=' "$target"; then
|
||||||
@@ -396,6 +430,16 @@ track_module_state(){
|
|||||||
rm -f "$host_rebuild_sentinel" 2>/dev/null || true
|
rm -f "$host_rebuild_sentinel" 2>/dev/null || true
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ "${MODULES_LOCAL_RUN:-0}" = "1" ]; then
|
||||||
|
local target_dir="${MODULES_HOST_DIR:-$(pwd)}"
|
||||||
|
local desired_user
|
||||||
|
desired_user="$(id -u):$(id -g)"
|
||||||
|
if [ -d "$target_dir" ]; then
|
||||||
|
chown -R "$desired_user" "$target_dir" >/dev/null 2>&1 || true
|
||||||
|
chmod -R ug+rwX "$target_dir" >/dev/null 2>&1 || true
|
||||||
|
fi
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
main(){
|
main(){
|
||||||
|
|||||||
@@ -5,6 +5,43 @@
|
|||||||
|
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
|
||||||
|
ENV_FILE="$PROJECT_ROOT/.env"
|
||||||
|
|
||||||
|
read_env_value(){
|
||||||
|
local key="$1" default="$2" value="${!key:-}"
|
||||||
|
if [ -z "$value" ] && [ -f "$ENV_FILE" ]; then
|
||||||
|
value="$(grep -E "^${key}=" "$ENV_FILE" 2>/dev/null | tail -n1 | cut -d'=' -f2- | tr -d '\r')"
|
||||||
|
fi
|
||||||
|
if [ -z "$value" ]; then
|
||||||
|
value="$default"
|
||||||
|
fi
|
||||||
|
echo "$value"
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve_project_name(){
|
||||||
|
local raw_name
|
||||||
|
raw_name="$(read_env_value COMPOSE_PROJECT_NAME "acore-compose")"
|
||||||
|
local sanitized
|
||||||
|
sanitized="$(echo "$raw_name" | tr '[:upper:]' '[:lower:]')"
|
||||||
|
sanitized="${sanitized// /-}"
|
||||||
|
sanitized="$(echo "$sanitized" | tr -cd 'a-z0-9_-')"
|
||||||
|
if [[ -z "$sanitized" ]]; then
|
||||||
|
sanitized="acore-compose"
|
||||||
|
elif [[ ! "$sanitized" =~ ^[a-z0-9] ]]; then
|
||||||
|
sanitized="ac${sanitized}"
|
||||||
|
fi
|
||||||
|
echo "$sanitized"
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve_project_image(){
|
||||||
|
local tag="$1"
|
||||||
|
local project_name
|
||||||
|
project_name="$(resolve_project_name)"
|
||||||
|
echo "${project_name}:${tag}"
|
||||||
|
}
|
||||||
|
|
||||||
usage(){
|
usage(){
|
||||||
cat <<'EOF_HELP'
|
cat <<'EOF_HELP'
|
||||||
Usage: $(basename "$0") --host HOST --user USER [options]
|
Usage: $(basename "$0") --host HOST --user USER [options]
|
||||||
@@ -57,7 +94,10 @@ fi
|
|||||||
|
|
||||||
PROJECT_DIR="${PROJECT_DIR:-/home/${USER}/acore-compose}"
|
PROJECT_DIR="${PROJECT_DIR:-/home/${USER}/acore-compose}"
|
||||||
REMOTE_STORAGE="${REMOTE_STORAGE:-${PROJECT_DIR}/storage}"
|
REMOTE_STORAGE="${REMOTE_STORAGE:-${PROJECT_DIR}/storage}"
|
||||||
LOCAL_STORAGE_ROOT="${STORAGE_PATH_LOCAL:-./local-storage}"
|
LOCAL_STORAGE_ROOT="${STORAGE_PATH_LOCAL:-}"
|
||||||
|
if [ -z "$LOCAL_STORAGE_ROOT" ]; then
|
||||||
|
LOCAL_STORAGE_ROOT="$(read_env_value STORAGE_PATH_LOCAL "./local-storage")"
|
||||||
|
fi
|
||||||
LOCAL_STORAGE_ROOT="${LOCAL_STORAGE_ROOT%/}"
|
LOCAL_STORAGE_ROOT="${LOCAL_STORAGE_ROOT%/}"
|
||||||
[ -z "$LOCAL_STORAGE_ROOT" ] && LOCAL_STORAGE_ROOT="."
|
[ -z "$LOCAL_STORAGE_ROOT" ] && LOCAL_STORAGE_ROOT="."
|
||||||
TARBALL="${TARBALL:-${LOCAL_STORAGE_ROOT}/images/acore-modules-images.tar}"
|
TARBALL="${TARBALL:-${LOCAL_STORAGE_ROOT}/images/acore-modules-images.tar}"
|
||||||
@@ -176,29 +216,24 @@ mkdir -p "$(dirname "$TARBALL")"
|
|||||||
# Check which images are available and collect them
|
# Check which images are available and collect them
|
||||||
IMAGES_TO_SAVE=()
|
IMAGES_TO_SAVE=()
|
||||||
|
|
||||||
# Check for custom module images (built by build.sh)
|
project_auth_modules="$(resolve_project_image "authserver-modules-latest")"
|
||||||
if docker image inspect uprightbass360/azerothcore-wotlk-playerbots:authserver-modules-latest >/dev/null 2>&1; then
|
project_world_modules="$(resolve_project_image "worldserver-modules-latest")"
|
||||||
IMAGES_TO_SAVE+=(uprightbass360/azerothcore-wotlk-playerbots:authserver-modules-latest)
|
project_auth_playerbots="$(resolve_project_image "authserver-playerbots")"
|
||||||
fi
|
project_world_playerbots="$(resolve_project_image "worldserver-playerbots")"
|
||||||
if docker image inspect uprightbass360/azerothcore-wotlk-playerbots:worldserver-modules-latest >/dev/null 2>&1; then
|
project_db_import="$(resolve_project_image "db-import-playerbots")"
|
||||||
IMAGES_TO_SAVE+=(uprightbass360/azerothcore-wotlk-playerbots:worldserver-modules-latest)
|
project_client_data="$(resolve_project_image "client-data-playerbots")"
|
||||||
fi
|
|
||||||
|
|
||||||
# Check for pre-compiled playerbots images
|
for image in \
|
||||||
if docker image inspect uprightbass360/azerothcore-wotlk-playerbots:worldserver-Playerbot >/dev/null 2>&1; then
|
"$project_auth_modules" \
|
||||||
IMAGES_TO_SAVE+=(uprightbass360/azerothcore-wotlk-playerbots:worldserver-Playerbot)
|
"$project_world_modules" \
|
||||||
fi
|
"$project_auth_playerbots" \
|
||||||
if docker image inspect uprightbass360/azerothcore-wotlk-playerbots:authserver-Playerbot >/dev/null 2>&1; then
|
"$project_world_playerbots" \
|
||||||
IMAGES_TO_SAVE+=(uprightbass360/azerothcore-wotlk-playerbots:authserver-Playerbot)
|
"$project_db_import" \
|
||||||
fi
|
"$project_client_data"; do
|
||||||
|
if docker image inspect "$image" >/dev/null 2>&1; then
|
||||||
# Check for standard AzerothCore images (fallback)
|
IMAGES_TO_SAVE+=("$image")
|
||||||
if docker image inspect acore/ac-wotlk-worldserver:modules-latest >/dev/null 2>&1; then
|
fi
|
||||||
IMAGES_TO_SAVE+=(acore/ac-wotlk-worldserver:modules-latest)
|
done
|
||||||
fi
|
|
||||||
if docker image inspect acore/ac-wotlk-authserver:modules-latest >/dev/null 2>&1; then
|
|
||||||
IMAGES_TO_SAVE+=(acore/ac-wotlk-authserver:modules-latest)
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ ${#IMAGES_TO_SAVE[@]} -eq 0 ]; then
|
if [ ${#IMAGES_TO_SAVE[@]} -eq 0 ]; then
|
||||||
echo "❌ No AzerothCore images found to migrate. Run './build.sh' first or pull standard images."
|
echo "❌ No AzerothCore images found to migrate. Run './build.sh' first or pull standard images."
|
||||||
|
|||||||
@@ -44,6 +44,80 @@ read_env(){
|
|||||||
echo "$value"
|
echo "$value"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
update_env_value(){
|
||||||
|
local key="$1" value="$2" env_file="$ENV_FILE"
|
||||||
|
[ -n "$env_file" ] || return 0
|
||||||
|
if [ ! -f "$env_file" ]; then
|
||||||
|
printf '%s=%s\n' "$key" "$value" >> "$env_file"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
if grep -q "^${key}=" "$env_file"; then
|
||||||
|
sed -i "s|^${key}=.*|${key}=${value}|" "$env_file"
|
||||||
|
else
|
||||||
|
printf '\n%s=%s\n' "$key" "$value" >> "$env_file"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
find_image_with_suffix(){
|
||||||
|
local suffix="$1"
|
||||||
|
docker images --format '{{.Repository}}:{{.Tag}}' | grep -E ":${suffix}$" | head -n1
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup_legacy_tags(){
|
||||||
|
local suffix="$1" keep_tag="$2"
|
||||||
|
docker images --format '{{.Repository}}:{{.Tag}}' | grep -E ":${suffix}$" | while read -r tag; do
|
||||||
|
[ "$tag" = "$keep_tag" ] && continue
|
||||||
|
docker rmi "$tag" >/dev/null 2>&1 || true
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
ensure_project_image_tag(){
|
||||||
|
local suffix="$1" target="$2"
|
||||||
|
if [ -n "$target" ] && docker image inspect "$target" >/dev/null 2>&1; then
|
||||||
|
cleanup_legacy_tags "$suffix" "$target"
|
||||||
|
echo "$target"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
local source
|
||||||
|
source="$(find_image_with_suffix "$suffix")"
|
||||||
|
if [ -z "$source" ]; then
|
||||||
|
echo ""
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
if docker tag "$source" "$target" >/dev/null 2>&1; then
|
||||||
|
if [ "$source" != "$target" ]; then
|
||||||
|
docker rmi "$source" >/dev/null 2>&1 || true
|
||||||
|
fi
|
||||||
|
cleanup_legacy_tags "$suffix" "$target"
|
||||||
|
echo "$target"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
echo ""
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve_project_name(){
|
||||||
|
local raw_name
|
||||||
|
raw_name="$(read_env COMPOSE_PROJECT_NAME "acore-compose")"
|
||||||
|
local sanitized
|
||||||
|
sanitized="$(echo "$raw_name" | tr '[:upper:]' '[:lower:]')"
|
||||||
|
sanitized="${sanitized// /-}"
|
||||||
|
sanitized="$(echo "$sanitized" | tr -cd 'a-z0-9_-')"
|
||||||
|
if [[ -z "$sanitized" ]]; then
|
||||||
|
sanitized="acore-compose"
|
||||||
|
elif [[ ! "$sanitized" =~ ^[a-z0-9] ]]; then
|
||||||
|
sanitized="ac${sanitized}"
|
||||||
|
fi
|
||||||
|
echo "$sanitized"
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve_project_image(){
|
||||||
|
local tag="$1"
|
||||||
|
local project_name
|
||||||
|
project_name="$(resolve_project_name)"
|
||||||
|
echo "${project_name}:${tag}"
|
||||||
|
}
|
||||||
|
|
||||||
default_source_path(){
|
default_source_path(){
|
||||||
local require_playerbot
|
local require_playerbot
|
||||||
require_playerbot="$(modules_require_playerbot_source)"
|
require_playerbot="$(modules_require_playerbot_source)"
|
||||||
@@ -283,21 +357,67 @@ get_template_value() {
|
|||||||
|
|
||||||
TARGET_AUTHSERVER_IMAGE="$(read_env AC_AUTHSERVER_IMAGE_MODULES "$(get_template_value "AC_AUTHSERVER_IMAGE_MODULES")")"
|
TARGET_AUTHSERVER_IMAGE="$(read_env AC_AUTHSERVER_IMAGE_MODULES "$(get_template_value "AC_AUTHSERVER_IMAGE_MODULES")")"
|
||||||
TARGET_WORLDSERVER_IMAGE="$(read_env AC_WORLDSERVER_IMAGE_MODULES "$(get_template_value "AC_WORLDSERVER_IMAGE_MODULES")")"
|
TARGET_WORLDSERVER_IMAGE="$(read_env AC_WORLDSERVER_IMAGE_MODULES "$(get_template_value "AC_WORLDSERVER_IMAGE_MODULES")")"
|
||||||
|
|
||||||
PLAYERBOTS_AUTHSERVER_IMAGE="$(read_env AC_AUTHSERVER_IMAGE_PLAYERBOTS "$(get_template_value "AC_AUTHSERVER_IMAGE_PLAYERBOTS")")"
|
PLAYERBOTS_AUTHSERVER_IMAGE="$(read_env AC_AUTHSERVER_IMAGE_PLAYERBOTS "$(get_template_value "AC_AUTHSERVER_IMAGE_PLAYERBOTS")")"
|
||||||
PLAYERBOTS_WORLDSERVER_IMAGE="$(read_env AC_WORLDSERVER_IMAGE_PLAYERBOTS "$(get_template_value "AC_WORLDSERVER_IMAGE_PLAYERBOTS")")"
|
PLAYERBOTS_WORLDSERVER_IMAGE="$(read_env AC_WORLDSERVER_IMAGE_PLAYERBOTS "$(get_template_value "AC_WORLDSERVER_IMAGE_PLAYERBOTS")")"
|
||||||
|
|
||||||
echo "🔁 Tagging modules images from playerbot build artifacts"
|
[ -z "$TARGET_AUTHSERVER_IMAGE" ] && TARGET_AUTHSERVER_IMAGE="$(resolve_project_image "authserver-modules-latest")"
|
||||||
if docker image inspect "$PLAYERBOTS_AUTHSERVER_IMAGE" >/dev/null 2>&1; then
|
[ -z "$TARGET_WORLDSERVER_IMAGE" ] && TARGET_WORLDSERVER_IMAGE="$(resolve_project_image "worldserver-modules-latest")"
|
||||||
docker tag "$PLAYERBOTS_AUTHSERVER_IMAGE" "$TARGET_AUTHSERVER_IMAGE"
|
[ -z "$PLAYERBOTS_AUTHSERVER_IMAGE" ] && PLAYERBOTS_AUTHSERVER_IMAGE="$(resolve_project_image "authserver-playerbots")"
|
||||||
|
[ -z "$PLAYERBOTS_WORLDSERVER_IMAGE" ] && PLAYERBOTS_WORLDSERVER_IMAGE="$(resolve_project_image "worldserver-playerbots")"
|
||||||
|
|
||||||
|
PLAYERBOTS_AUTHSERVER_IMAGE="$(ensure_project_image_tag "authserver-Playerbot" "$(resolve_project_image "authserver-playerbots")")"
|
||||||
|
if [ -z "$PLAYERBOTS_AUTHSERVER_IMAGE" ]; then
|
||||||
|
echo "⚠️ Warning: unable to ensure project tag for authserver playerbots image"
|
||||||
else
|
else
|
||||||
echo "⚠️ Warning: $PLAYERBOTS_AUTHSERVER_IMAGE not found, skipping authserver tag"
|
update_env_value "AC_AUTHSERVER_IMAGE_PLAYERBOTS" "$PLAYERBOTS_AUTHSERVER_IMAGE"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if docker image inspect "$PLAYERBOTS_WORLDSERVER_IMAGE" >/dev/null 2>&1; then
|
PLAYERBOTS_WORLDSERVER_IMAGE="$(ensure_project_image_tag "worldserver-Playerbot" "$(resolve_project_image "worldserver-playerbots")")"
|
||||||
docker tag "$PLAYERBOTS_WORLDSERVER_IMAGE" "$TARGET_WORLDSERVER_IMAGE"
|
if [ -z "$PLAYERBOTS_WORLDSERVER_IMAGE" ]; then
|
||||||
|
echo "⚠️ Warning: unable to ensure project tag for worldserver playerbots image"
|
||||||
else
|
else
|
||||||
echo "⚠️ Warning: $PLAYERBOTS_WORLDSERVER_IMAGE not found, skipping worldserver tag"
|
update_env_value "AC_WORLDSERVER_IMAGE_PLAYERBOTS" "$PLAYERBOTS_WORLDSERVER_IMAGE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "🔁 Tagging modules images from playerbot build artifacts"
|
||||||
|
if [ -n "$PLAYERBOTS_AUTHSERVER_IMAGE" ] && docker image inspect "$PLAYERBOTS_AUTHSERVER_IMAGE" >/dev/null 2>&1; then
|
||||||
|
if docker tag "$PLAYERBOTS_AUTHSERVER_IMAGE" "$TARGET_AUTHSERVER_IMAGE"; then
|
||||||
|
echo "✅ Tagged $TARGET_AUTHSERVER_IMAGE from $PLAYERBOTS_AUTHSERVER_IMAGE"
|
||||||
|
update_env_value "AC_AUTHSERVER_IMAGE_PLAYERBOTS" "$PLAYERBOTS_AUTHSERVER_IMAGE"
|
||||||
|
update_env_value "AC_AUTHSERVER_IMAGE_MODULES" "$TARGET_AUTHSERVER_IMAGE"
|
||||||
|
else
|
||||||
|
echo "⚠️ Failed to tag $TARGET_AUTHSERVER_IMAGE from $PLAYERBOTS_AUTHSERVER_IMAGE"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "⚠️ Warning: unable to locate project-tagged authserver playerbots image"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "$PLAYERBOTS_WORLDSERVER_IMAGE" ] && docker image inspect "$PLAYERBOTS_WORLDSERVER_IMAGE" >/dev/null 2>&1; then
|
||||||
|
if docker tag "$PLAYERBOTS_WORLDSERVER_IMAGE" "$TARGET_WORLDSERVER_IMAGE"; then
|
||||||
|
echo "✅ Tagged $TARGET_WORLDSERVER_IMAGE from $PLAYERBOTS_WORLDSERVER_IMAGE"
|
||||||
|
update_env_value "AC_WORLDSERVER_IMAGE_PLAYERBOTS" "$PLAYERBOTS_WORLDSERVER_IMAGE"
|
||||||
|
update_env_value "AC_WORLDSERVER_IMAGE_MODULES" "$TARGET_WORLDSERVER_IMAGE"
|
||||||
|
else
|
||||||
|
echo "⚠️ Failed to tag $TARGET_WORLDSERVER_IMAGE from $PLAYERBOTS_WORLDSERVER_IMAGE"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "⚠️ Warning: unable to locate project-tagged worldserver playerbots image"
|
||||||
|
fi
|
||||||
|
|
||||||
|
TARGET_DB_IMPORT_IMAGE="$(resolve_project_image "db-import-playerbots")"
|
||||||
|
DB_IMPORT_IMAGE="$(ensure_project_image_tag "db-import-Playerbot" "$TARGET_DB_IMPORT_IMAGE")"
|
||||||
|
if [ -n "$DB_IMPORT_IMAGE" ]; then
|
||||||
|
update_env_value "AC_DB_IMPORT_IMAGE" "$DB_IMPORT_IMAGE"
|
||||||
|
else
|
||||||
|
echo "⚠️ Warning: unable to ensure project tag for db-import image"
|
||||||
|
fi
|
||||||
|
|
||||||
|
TARGET_CLIENT_DATA_IMAGE="$(resolve_project_image "client-data-playerbots")"
|
||||||
|
CLIENT_DATA_IMAGE="$(ensure_project_image_tag "client-data-Playerbot" "$TARGET_CLIENT_DATA_IMAGE")"
|
||||||
|
if [ -n "$CLIENT_DATA_IMAGE" ]; then
|
||||||
|
update_env_value "AC_CLIENT_DATA_IMAGE_PLAYERBOTS" "$CLIENT_DATA_IMAGE"
|
||||||
|
else
|
||||||
|
echo "⚠️ Warning: unable to ensure project tag for client-data image"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
show_rebuild_step 5 5 "Cleaning up build containers"
|
show_rebuild_step 5 5 "Cleaning up build containers"
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ fi
|
|||||||
|
|
||||||
ACORE_REPO_STANDARD="${ACORE_REPO_STANDARD:-https://github.com/azerothcore/azerothcore-wotlk.git}"
|
ACORE_REPO_STANDARD="${ACORE_REPO_STANDARD:-https://github.com/azerothcore/azerothcore-wotlk.git}"
|
||||||
ACORE_BRANCH_STANDARD="${ACORE_BRANCH_STANDARD:-master}"
|
ACORE_BRANCH_STANDARD="${ACORE_BRANCH_STANDARD:-master}"
|
||||||
ACORE_REPO_PLAYERBOTS="${ACORE_REPO_PLAYERBOTS:-https://github.com/uprightbass360/azerothcore-wotlk-playerbots.git}"
|
ACORE_REPO_PLAYERBOTS="${ACORE_REPO_PLAYERBOTS:-https://github.com/mod-playerbots/azerothcore-wotlk.git}"
|
||||||
ACORE_BRANCH_PLAYERBOTS="${ACORE_BRANCH_PLAYERBOTS:-Playerbot}"
|
ACORE_BRANCH_PLAYERBOTS="${ACORE_BRANCH_PLAYERBOTS:-Playerbot}"
|
||||||
|
|
||||||
# Repository and branch selection based on playerbots mode
|
# Repository and branch selection based on playerbots mode
|
||||||
|
|||||||
@@ -97,6 +97,28 @@ read_env(){
|
|||||||
echo "$value"
|
echo "$value"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resolve_project_name(){
|
||||||
|
local raw_name
|
||||||
|
raw_name="$(read_env COMPOSE_PROJECT_NAME "acore-compose")"
|
||||||
|
local sanitized
|
||||||
|
sanitized="$(echo "$raw_name" | tr '[:upper:]' '[:lower:]')"
|
||||||
|
sanitized="${sanitized// /-}"
|
||||||
|
sanitized="$(echo "$sanitized" | tr -cd 'a-z0-9_-')"
|
||||||
|
if [[ -z "$sanitized" ]]; then
|
||||||
|
sanitized="acore-compose"
|
||||||
|
elif [[ ! "$sanitized" =~ ^[a-z0-9] ]]; then
|
||||||
|
sanitized="ac${sanitized}"
|
||||||
|
fi
|
||||||
|
echo "$sanitized"
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve_project_image(){
|
||||||
|
local tag="$1"
|
||||||
|
local project_name
|
||||||
|
project_name="$(resolve_project_name)"
|
||||||
|
echo "${project_name}:${tag}"
|
||||||
|
}
|
||||||
|
|
||||||
canonical_path(){
|
canonical_path(){
|
||||||
local path="$1"
|
local path="$1"
|
||||||
if command -v realpath >/dev/null 2>&1; then
|
if command -v realpath >/dev/null 2>&1; then
|
||||||
@@ -265,7 +287,7 @@ echo "🎯 Target profile: services-$TARGET_PROFILE"
|
|||||||
|
|
||||||
# Check if source rebuild is needed for modules profile
|
# Check if source rebuild is needed for modules profile
|
||||||
REBUILD_NEEDED=0
|
REBUILD_NEEDED=0
|
||||||
TARGET_WORLDSERVER_IMAGE_MODULES="$(read_env AC_WORLDSERVER_IMAGE_MODULES "uprightbass360/azerothcore-wotlk-playerbots:worldserver-modules-latest")"
|
TARGET_WORLDSERVER_IMAGE_MODULES="$(read_env AC_WORLDSERVER_IMAGE_MODULES "$(resolve_project_image "worldserver-modules-latest")")"
|
||||||
if [ "$TARGET_PROFILE" = "modules" ]; then
|
if [ "$TARGET_PROFILE" = "modules" ]; then
|
||||||
# Check if source image exists
|
# Check if source image exists
|
||||||
if ! docker image inspect "$TARGET_WORLDSERVER_IMAGE_MODULES" >/dev/null 2>&1; then
|
if ! docker image inspect "$TARGET_WORLDSERVER_IMAGE_MODULES" >/dev/null 2>&1; then
|
||||||
|
|||||||
48
setup.sh
48
setup.sh
@@ -43,6 +43,25 @@ get_template_value() {
|
|||||||
echo "$value"
|
echo "$value"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sanitize_project_name(){
|
||||||
|
local raw="$1"
|
||||||
|
local sanitized
|
||||||
|
sanitized="$(echo "$raw" | tr '[:upper:]' '[:lower:]')"
|
||||||
|
sanitized="${sanitized// /-}"
|
||||||
|
sanitized="$(echo "$sanitized" | tr -cd 'a-z0-9_-')"
|
||||||
|
if [[ -z "$sanitized" ]]; then
|
||||||
|
sanitized="acore-compose"
|
||||||
|
elif [[ ! "$sanitized" =~ ^[a-z0-9] ]]; then
|
||||||
|
sanitized="ac${sanitized}"
|
||||||
|
fi
|
||||||
|
echo "$sanitized"
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve_project_image_tag(){
|
||||||
|
local project="$1" tag="$2"
|
||||||
|
echo "${project}:${tag}"
|
||||||
|
}
|
||||||
|
|
||||||
declare -A TEMPLATE_VALUE_MAP=(
|
declare -A TEMPLATE_VALUE_MAP=(
|
||||||
[DEFAULT_MYSQL_PASSWORD]=MYSQL_ROOT_PASSWORD
|
[DEFAULT_MYSQL_PASSWORD]=MYSQL_ROOT_PASSWORD
|
||||||
[DEFAULT_REALM_PORT]=WORLD_EXTERNAL_PORT
|
[DEFAULT_REALM_PORT]=WORLD_EXTERNAL_PORT
|
||||||
@@ -905,6 +924,8 @@ fi
|
|||||||
local AC_WORLDSERVER_IMAGE_PLAYERBOTS_VALUE="$DEFAULT_WORLD_IMAGE_PLAYERBOTS"
|
local AC_WORLDSERVER_IMAGE_PLAYERBOTS_VALUE="$DEFAULT_WORLD_IMAGE_PLAYERBOTS"
|
||||||
local AC_AUTHSERVER_IMAGE_MODULES_VALUE="$DEFAULT_AUTH_IMAGE_MODULES"
|
local AC_AUTHSERVER_IMAGE_MODULES_VALUE="$DEFAULT_AUTH_IMAGE_MODULES"
|
||||||
local AC_WORLDSERVER_IMAGE_MODULES_VALUE="$DEFAULT_WORLD_IMAGE_MODULES"
|
local AC_WORLDSERVER_IMAGE_MODULES_VALUE="$DEFAULT_WORLD_IMAGE_MODULES"
|
||||||
|
local AC_CLIENT_DATA_IMAGE_PLAYERBOTS_VALUE="$DEFAULT_CLIENT_DATA_IMAGE_PLAYERBOTS"
|
||||||
|
local AC_DB_IMPORT_IMAGE_VALUE="$DEFAULT_AC_DB_IMPORT_IMAGE"
|
||||||
|
|
||||||
local mod_var
|
local mod_var
|
||||||
for mod_var in "${!MODULE_ENABLE_SET[@]}"; do
|
for mod_var in "${!MODULE_ENABLE_SET[@]}"; do
|
||||||
@@ -1040,11 +1061,6 @@ fi
|
|||||||
|
|
||||||
export NEEDS_CXX_REBUILD
|
export NEEDS_CXX_REBUILD
|
||||||
|
|
||||||
if [ "$MODULE_PLAYERBOTS" = "1" ]; then
|
|
||||||
AC_AUTHSERVER_IMAGE_PLAYERBOTS_VALUE="$DEFAULT_AUTH_IMAGE_PLAYERBOTS"
|
|
||||||
AC_WORLDSERVER_IMAGE_PLAYERBOTS_VALUE="$DEFAULT_WORLD_IMAGE_PLAYERBOTS"
|
|
||||||
fi
|
|
||||||
|
|
||||||
local SUMMARY_MODE_TEXT="$module_mode_label"
|
local SUMMARY_MODE_TEXT="$module_mode_label"
|
||||||
if [ -z "$SUMMARY_MODE_TEXT" ]; then
|
if [ -z "$SUMMARY_MODE_TEXT" ]; then
|
||||||
SUMMARY_MODE_TEXT="$MODE_SELECTION"
|
SUMMARY_MODE_TEXT="$MODE_SELECTION"
|
||||||
@@ -1186,7 +1202,23 @@ fi
|
|||||||
MODULE_ELUNA=${MODULE_ELUNA:-$DEFAULT_MODULE_ELUNA}
|
MODULE_ELUNA=${MODULE_ELUNA:-$DEFAULT_MODULE_ELUNA}
|
||||||
BACKUP_PATH=${BACKUP_PATH:-$DEFAULT_BACKUP_PATH}
|
BACKUP_PATH=${BACKUP_PATH:-$DEFAULT_BACKUP_PATH}
|
||||||
|
|
||||||
{
|
local project_image_prefix
|
||||||
|
project_image_prefix="$(sanitize_project_name "$DEFAULT_COMPOSE_PROJECT_NAME")"
|
||||||
|
if [ "$MODULE_PLAYERBOTS" = "1" ] || [ "$NEEDS_CXX_REBUILD" = "1" ]; then
|
||||||
|
AC_AUTHSERVER_IMAGE_PLAYERBOTS_VALUE="$(resolve_project_image_tag "$project_image_prefix" "authserver-playerbots")"
|
||||||
|
AC_WORLDSERVER_IMAGE_PLAYERBOTS_VALUE="$(resolve_project_image_tag "$project_image_prefix" "worldserver-playerbots")"
|
||||||
|
AC_DB_IMPORT_IMAGE_VALUE="$(resolve_project_image_tag "$project_image_prefix" "db-import-playerbots")"
|
||||||
|
AC_CLIENT_DATA_IMAGE_PLAYERBOTS_VALUE="$(resolve_project_image_tag "$project_image_prefix" "client-data-playerbots")"
|
||||||
|
else
|
||||||
|
AC_AUTHSERVER_IMAGE_PLAYERBOTS_VALUE="$DEFAULT_AUTH_IMAGE_PLAYERBOTS"
|
||||||
|
AC_WORLDSERVER_IMAGE_PLAYERBOTS_VALUE="$DEFAULT_WORLD_IMAGE_PLAYERBOTS"
|
||||||
|
AC_DB_IMPORT_IMAGE_VALUE="$DEFAULT_AC_DB_IMPORT_IMAGE"
|
||||||
|
AC_CLIENT_DATA_IMAGE_PLAYERBOTS_VALUE="$DEFAULT_CLIENT_DATA_IMAGE_PLAYERBOTS"
|
||||||
|
fi
|
||||||
|
AC_AUTHSERVER_IMAGE_MODULES_VALUE="$(resolve_project_image_tag "$project_image_prefix" "authserver-modules-latest")"
|
||||||
|
AC_WORLDSERVER_IMAGE_MODULES_VALUE="$(resolve_project_image_tag "$project_image_prefix" "worldserver-modules-latest")"
|
||||||
|
|
||||||
|
{
|
||||||
cat <<EOF
|
cat <<EOF
|
||||||
# Generated by ac-compose/setup.sh
|
# Generated by ac-compose/setup.sh
|
||||||
|
|
||||||
@@ -1219,7 +1251,7 @@ DB_AUTH_NAME=$DEFAULT_DB_AUTH_NAME
|
|||||||
DB_WORLD_NAME=$DEFAULT_DB_WORLD_NAME
|
DB_WORLD_NAME=$DEFAULT_DB_WORLD_NAME
|
||||||
DB_CHARACTERS_NAME=$DEFAULT_DB_CHARACTERS_NAME
|
DB_CHARACTERS_NAME=$DEFAULT_DB_CHARACTERS_NAME
|
||||||
DB_PLAYERBOTS_NAME=${DB_PLAYERBOTS_NAME:-$DEFAULT_DB_PLAYERBOTS_NAME}
|
DB_PLAYERBOTS_NAME=${DB_PLAYERBOTS_NAME:-$DEFAULT_DB_PLAYERBOTS_NAME}
|
||||||
AC_DB_IMPORT_IMAGE=$DEFAULT_AC_DB_IMPORT_IMAGE
|
AC_DB_IMPORT_IMAGE=$AC_DB_IMPORT_IMAGE_VALUE
|
||||||
|
|
||||||
# Services (images)
|
# Services (images)
|
||||||
AC_AUTHSERVER_IMAGE=$DEFAULT_AC_AUTHSERVER_IMAGE
|
AC_AUTHSERVER_IMAGE=$DEFAULT_AC_AUTHSERVER_IMAGE
|
||||||
@@ -1231,7 +1263,7 @@ AC_WORLDSERVER_IMAGE_MODULES=${AC_WORLDSERVER_IMAGE_MODULES_VALUE}
|
|||||||
|
|
||||||
# Client data images
|
# Client data images
|
||||||
AC_CLIENT_DATA_IMAGE=$DEFAULT_AC_CLIENT_DATA_IMAGE
|
AC_CLIENT_DATA_IMAGE=$DEFAULT_AC_CLIENT_DATA_IMAGE
|
||||||
AC_CLIENT_DATA_IMAGE_PLAYERBOTS=$DEFAULT_CLIENT_DATA_IMAGE_PLAYERBOTS
|
AC_CLIENT_DATA_IMAGE_PLAYERBOTS=$AC_CLIENT_DATA_IMAGE_PLAYERBOTS_VALUE
|
||||||
CLIENT_DATA_CACHE_PATH=$DEFAULT_CLIENT_DATA_CACHE_PATH
|
CLIENT_DATA_CACHE_PATH=$DEFAULT_CLIENT_DATA_CACHE_PATH
|
||||||
CLIENT_DATA_VOLUME=${CLIENT_DATA_VOLUME:-$DEFAULT_CLIENT_DATA_VOLUME}
|
CLIENT_DATA_VOLUME=${CLIENT_DATA_VOLUME:-$DEFAULT_CLIENT_DATA_VOLUME}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user