new repo and uid features

This commit is contained in:
uprightbass360
2025-11-01 04:46:18 -04:00
parent d59c785f11
commit 158cd45297
11 changed files with 461 additions and 68 deletions

View File

@@ -18,6 +18,27 @@ ok(){ printf '%b\n' "${GREEN}✅ $*${NC}"; }
warn(){ printf '%b\n' "${YELLOW}⚠️ $*${NC}"; }
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(){
if ! command -v python3 >/dev/null 2>&1; then
err "python3 is required but not installed in PATH"
@@ -193,11 +214,24 @@ update_playerbots_db_info(){
return 0
fi
local host="${CONTAINER_MYSQL:-${MYSQL_HOST:-127.0.0.1}}"
local port="${MYSQL_PORT:-3306}"
local user="${MYSQL_USER:-root}"
local pass="${MYSQL_ROOT_PASSWORD:-acore}"
local db="${DB_PLAYERBOTS_NAME:-acore_playerbots}"
local host
host="$(read_env_value CONTAINER_MYSQL)"
if [ -z "$host" ]; then
host="$(read_env_value MYSQL_HOST)"
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}"
if grep -qE '^[[:space:]]*PlayerbotsDatabaseInfo[[:space:]]*=' "$target"; then
@@ -396,6 +430,16 @@ track_module_state(){
rm -f "$host_rebuild_sentinel" 2>/dev/null || true
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(){

View File

@@ -5,6 +5,43 @@
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(){
cat <<'EOF_HELP'
Usage: $(basename "$0") --host HOST --user USER [options]
@@ -57,7 +94,10 @@ fi
PROJECT_DIR="${PROJECT_DIR:-/home/${USER}/acore-compose}"
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%/}"
[ -z "$LOCAL_STORAGE_ROOT" ] && LOCAL_STORAGE_ROOT="."
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
IMAGES_TO_SAVE=()
# Check for custom module images (built by build.sh)
if docker image inspect uprightbass360/azerothcore-wotlk-playerbots:authserver-modules-latest >/dev/null 2>&1; then
IMAGES_TO_SAVE+=(uprightbass360/azerothcore-wotlk-playerbots:authserver-modules-latest)
fi
if docker image inspect uprightbass360/azerothcore-wotlk-playerbots:worldserver-modules-latest >/dev/null 2>&1; then
IMAGES_TO_SAVE+=(uprightbass360/azerothcore-wotlk-playerbots:worldserver-modules-latest)
fi
project_auth_modules="$(resolve_project_image "authserver-modules-latest")"
project_world_modules="$(resolve_project_image "worldserver-modules-latest")"
project_auth_playerbots="$(resolve_project_image "authserver-playerbots")"
project_world_playerbots="$(resolve_project_image "worldserver-playerbots")"
project_db_import="$(resolve_project_image "db-import-playerbots")"
project_client_data="$(resolve_project_image "client-data-playerbots")"
# Check for pre-compiled playerbots images
if docker image inspect uprightbass360/azerothcore-wotlk-playerbots:worldserver-Playerbot >/dev/null 2>&1; then
IMAGES_TO_SAVE+=(uprightbass360/azerothcore-wotlk-playerbots:worldserver-Playerbot)
fi
if docker image inspect uprightbass360/azerothcore-wotlk-playerbots:authserver-Playerbot >/dev/null 2>&1; then
IMAGES_TO_SAVE+=(uprightbass360/azerothcore-wotlk-playerbots:authserver-Playerbot)
fi
# Check for standard AzerothCore images (fallback)
if docker image inspect acore/ac-wotlk-worldserver:modules-latest >/dev/null 2>&1; then
IMAGES_TO_SAVE+=(acore/ac-wotlk-worldserver:modules-latest)
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
for image in \
"$project_auth_modules" \
"$project_world_modules" \
"$project_auth_playerbots" \
"$project_world_playerbots" \
"$project_db_import" \
"$project_client_data"; do
if docker image inspect "$image" >/dev/null 2>&1; then
IMAGES_TO_SAVE+=("$image")
fi
done
if [ ${#IMAGES_TO_SAVE[@]} -eq 0 ]; then
echo "❌ No AzerothCore images found to migrate. Run './build.sh' first or pull standard images."

View File

@@ -44,6 +44,80 @@ read_env(){
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(){
local require_playerbot
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_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_WORLDSERVER_IMAGE="$(read_env AC_WORLDSERVER_IMAGE_PLAYERBOTS "$(get_template_value "AC_WORLDSERVER_IMAGE_PLAYERBOTS")")"
echo "🔁 Tagging modules images from playerbot build artifacts"
if docker image inspect "$PLAYERBOTS_AUTHSERVER_IMAGE" >/dev/null 2>&1; then
docker tag "$PLAYERBOTS_AUTHSERVER_IMAGE" "$TARGET_AUTHSERVER_IMAGE"
[ -z "$TARGET_AUTHSERVER_IMAGE" ] && TARGET_AUTHSERVER_IMAGE="$(resolve_project_image "authserver-modules-latest")"
[ -z "$TARGET_WORLDSERVER_IMAGE" ] && TARGET_WORLDSERVER_IMAGE="$(resolve_project_image "worldserver-modules-latest")"
[ -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
echo "⚠️ Warning: $PLAYERBOTS_AUTHSERVER_IMAGE not found, skipping authserver tag"
update_env_value "AC_AUTHSERVER_IMAGE_PLAYERBOTS" "$PLAYERBOTS_AUTHSERVER_IMAGE"
fi
if docker image inspect "$PLAYERBOTS_WORLDSERVER_IMAGE" >/dev/null 2>&1; then
docker tag "$PLAYERBOTS_WORLDSERVER_IMAGE" "$TARGET_WORLDSERVER_IMAGE"
PLAYERBOTS_WORLDSERVER_IMAGE="$(ensure_project_image_tag "worldserver-Playerbot" "$(resolve_project_image "worldserver-playerbots")")"
if [ -z "$PLAYERBOTS_WORLDSERVER_IMAGE" ]; then
echo "⚠️ Warning: unable to ensure project tag for worldserver playerbots image"
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
show_rebuild_step 5 5 "Cleaning up build containers"

View File

@@ -69,7 +69,7 @@ fi
ACORE_REPO_STANDARD="${ACORE_REPO_STANDARD:-https://github.com/azerothcore/azerothcore-wotlk.git}"
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}"
# Repository and branch selection based on playerbots mode

View File

@@ -97,6 +97,28 @@ read_env(){
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(){
local path="$1"
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
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
# Check if source image exists
if ! docker image inspect "$TARGET_WORLDSERVER_IMAGE_MODULES" >/dev/null 2>&1; then