Introduce dynamic overrides and rename module manifest

This commit is contained in:
uprightbass360
2025-11-08 01:49:21 -05:00
parent 662af4b3a7
commit 622fd518d2
29 changed files with 261 additions and 155 deletions

View File

@@ -2,6 +2,14 @@
# Docker Compose will auto-load .env in the same folder as docker-compose.yml. # Docker Compose will auto-load .env in the same folder as docker-compose.yml.
# Template for acore-compose profiles-based compose # Template for acore-compose profiles-based compose
# =====================
# Compose overrides (set to 1 to include matching file under compose-overrides/)
# =====================
# mysql-expose.yml -> exposes MySQL externally via COMPOSE_OVERRIDE_MYSQL_EXPOSE_ENABLED
# worldserver-debug-logging.yml -> raises log verbosity via COMPOSE_OVERRIDE_WORLDSERVER_DEBUG_LOGGING_ENABLED
COMPOSE_OVERRIDE_MYSQL_EXPOSE_ENABLED=0
COMPOSE_OVERRIDE_WORLDSERVER_DEBUG_LOGGING_ENABLED=0
# ===================== # =====================
# Project name # Project name
# ===================== # =====================
@@ -43,10 +51,10 @@ CONTAINER_POST_INSTALL=ac-post-install
# ===================== # =====================
# Images # Images
# ===================== # =====================
AC_DB_IMPORT_IMAGE=acore/ac-wotlk-db-import:14.0.0-dev AC_DB_IMPORT_IMAGE=acore/ac-wotlk-db-import:master
# Services (Standard) # Services (Standard)
AC_AUTHSERVER_IMAGE=acore/ac-wotlk-authserver:14.0.0-dev AC_AUTHSERVER_IMAGE=acore/ac-wotlk-authserver:master
AC_WORLDSERVER_IMAGE=acore/ac-wotlk-worldserver:14.0.0-dev AC_WORLDSERVER_IMAGE=acore/ac-wotlk-worldserver:master
# Services (Playerbots) # Services (Playerbots)
AC_AUTHSERVER_IMAGE_PLAYERBOTS=acore-compose:authserver-playerbots AC_AUTHSERVER_IMAGE_PLAYERBOTS=acore-compose:authserver-playerbots
AC_WORLDSERVER_IMAGE_PLAYERBOTS=acore-compose:worldserver-playerbots AC_WORLDSERVER_IMAGE_PLAYERBOTS=acore-compose:worldserver-playerbots
@@ -55,7 +63,7 @@ AC_WORLDSERVER_IMAGE_PLAYERBOTS=acore-compose:worldserver-playerbots
AC_AUTHSERVER_IMAGE_MODULES=acore-compose:authserver-modules-latest AC_AUTHSERVER_IMAGE_MODULES=acore-compose:authserver-modules-latest
AC_WORLDSERVER_IMAGE_MODULES=acore-compose: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:master
AC_CLIENT_DATA_IMAGE_PLAYERBOTS=uprightbass360/azerothcore-wotlk-playerbots:client-data-Playerbot AC_CLIENT_DATA_IMAGE_PLAYERBOTS=uprightbass360/azerothcore-wotlk-playerbots:client-data-Playerbot
# Build artifacts # Build artifacts
DOCKER_IMAGE_TAG=master DOCKER_IMAGE_TAG=master
@@ -101,7 +109,6 @@ MYSQL_ROOT_HOST=%
MYSQL_USER=root MYSQL_USER=root
MYSQL_PORT=3306 MYSQL_PORT=3306
MYSQL_EXTERNAL_PORT=64306 MYSQL_EXTERNAL_PORT=64306
MYSQL_EXPOSE_PORT=0
MYSQL_CHARACTER_SET=utf8mb4 MYSQL_CHARACTER_SET=utf8mb4
MYSQL_COLLATION=utf8mb4_unicode_ci MYSQL_COLLATION=utf8mb4_unicode_ci
MYSQL_MAX_CONNECTIONS=1000 MYSQL_MAX_CONNECTIONS=1000

View File

@@ -97,6 +97,7 @@ cd AzerothCore-RealmMaster
The setup wizard will guide you through: The setup wizard will guide you through:
- **Server Configuration**: IP address, ports, timezone - **Server Configuration**: IP address, ports, timezone
- **Module Selection**: Choose from 30+ available modules or use presets - **Module Selection**: Choose from 30+ available modules or use presets
- **Module Definitions**: Customize defaults in `config/module-manifest.json` and optional presets under `config/module-profiles/`
- **Storage Paths**: Configure NFS/local storage locations - **Storage Paths**: Configure NFS/local storage locations
- **Playerbot Settings**: Max bots, account limits (if enabled) - **Playerbot Settings**: Max bots, account limits (if enabled)
- **Backup Settings**: Retention policies for automated backups - **Backup Settings**: Retention policies for automated backups
@@ -116,7 +117,7 @@ The setup wizard will guide you through:
**Required when:** **Required when:**
- Playerbots enabled (`MODULE_PLAYERBOTS=1`) - Playerbots enabled (`MODULE_PLAYERBOTS=1`)
- Any C++ module enabled (modules with `"type": "cpp"` in `config/modules.json`) - Any C++ module enabled (modules with `"type": "cpp"` in `config/module-manifest.json`)
**Build process:** **Build process:**
1. Clones AzerothCore source to `local-storage/source/` 1. Clones AzerothCore source to `local-storage/source/`
@@ -249,7 +250,7 @@ The remote deployment process transfers:
- ❌ Build artifacts (source code, compilation files stay local) - ❌ Build artifacts (source code, compilation files stay local)
#### Module Presets #### Module Presets
- Define JSON presets in `profiles/*.json`. Each file contains: - Define JSON presets in `config/module-profiles/*.json`. Each file contains:
- `modules` (array, required) list of `MODULE_*` identifiers to enable. - `modules` (array, required) list of `MODULE_*` identifiers to enable.
- `label` (string, optional) text shown in the setup menu (emoji welcome). - `label` (string, optional) text shown in the setup menu (emoji welcome).
- `description` (string, optional) short help text for maintainers. - `description` (string, optional) short help text for maintainers.
@@ -266,11 +267,12 @@ The remote deployment process transfers:
``` ```
- `setup.sh` automatically adds these presets to the module menu and enables the listed modules when selected or when `--module-config <name>` is provided. - `setup.sh` automatically adds these presets to the module menu and enables the listed modules when selected or when `--module-config <name>` is provided.
- Built-in presets: - Built-in presets:
- `profiles/suggested-modules.json` default solo-friendly QoL stack. - `config/module-profiles/suggested-modules.json` default solo-friendly QoL stack.
- `profiles/playerbots-suggested-modules.json` suggested stack plus playerbots. - `config/module-profiles/playerbots-suggested-modules.json` suggested stack plus playerbots.
- `profiles/playerbots-only.json` playerbot-focused profile (adjust `--playerbot-max-bots`). - `config/module-profiles/playerbots-only.json` playerbot-focused profile (adjust `--playerbot-max-bots`).
- Custom example: - Custom example:
- `profiles/sam.json` Sam's playerbot-focused profile (set `--playerbot-max-bots 3000` when using this preset). - `config/module-profiles/sam.json` Sam's playerbot-focused profile (set `--playerbot-max-bots 3000` when using this preset).
- Module metadata lives in `config/module-manifest.json`; update that file if you need to add new modules or change repositories/branches.
### Post-Installation Steps ### Post-Installation Steps
@@ -757,7 +759,7 @@ flowchart TB
| Service / Container | Role | Ports (host → container) | Profile | | Service / Container | Role | Ports (host → container) | Profile |
|---------------------|------|--------------------------|---------| |---------------------|------|--------------------------|---------|
| `ac-mysql` | MySQL 8.0 database | *(optional)* `64306 → 3306` (`MYSQL_EXPOSE_PORT=1`) | `db` | | `ac-mysql` | MySQL 8.0 database | *(optional)* `64306 → 3306` (`COMPOSE_OVERRIDE_MYSQL_EXPOSE_ENABLED=1`) | `db` |
| `ac-db-init` | Database schema initialization | | `db` | | `ac-db-init` | Database schema initialization | | `db` |
| `ac-db-import` | Database content import | | `db` | | `ac-db-import` | Database content import | | `db` |
| `ac-backup` | Automated backup system | | `db` | | `ac-backup` | Automated backup system | | `db` |
@@ -775,10 +777,22 @@ flowchart TB
### Database Hardening ### Database Hardening
- **MySQL port exposure** By default `MYSQL_EXPOSE_PORT=0`, so `ac-mysql` is reachable only from the internal Docker network. Set `MYSQL_EXPOSE_PORT=1` to publish `${MYSQL_EXTERNAL_PORT}` on the host; RealmMaster scripts automatically include `docker-compose.mysql-expose.yml` so the override Just Works. If you invoke Compose manually, remember to add `-f docker-compose.mysql-expose.yml`. - **MySQL port exposure** By default `COMPOSE_OVERRIDE_MYSQL_EXPOSE_ENABLED=0`, so `ac-mysql` is reachable only from the internal Docker network. Set it to `1` to publish `${MYSQL_EXTERNAL_PORT}` on the host; RealmMaster scripts automatically include `compose-overrides/mysql-expose.yml` so the override Just Works. If you invoke Compose manually, remember to add `-f compose-overrides/mysql-expose.yml`. You can follow the same `COMPOSE_OVERRIDE_<NAME>_ENABLED=1` pattern for any custom override files you drop into `compose-overrides/`.
- **Worldserver debug logging** Need extra verbosity temporarily? Flip `COMPOSE_OVERRIDE_WORLDSERVER_DEBUG_LOGGING_ENABLED=1` to include `compose-overrides/worldserver-debug-logging.yml`, which bumps `AC_LOG_LEVEL` across all worldserver profiles. Turn it back off once youre done to avoid noisy logs.
- **Binary logging toggle** `MYSQL_DISABLE_BINLOG=1` appends `--skip-log-bin` via the MySQL wrapper entrypoint to keep disk churn low (and match Playerbot guidance). Flip the flag to `0` to re-enable binlogs for debugging or replication. - **Binary logging toggle** `MYSQL_DISABLE_BINLOG=1` appends `--skip-log-bin` via the MySQL wrapper entrypoint to keep disk churn low (and match Playerbot guidance). Flip the flag to `0` to re-enable binlogs for debugging or replication.
- **Drop-in configs** Any `.cnf` placed in `${STORAGE_PATH}/config/mysql/conf.d` (exposed via `MYSQL_CONFIG_DIR`) is mounted into `/etc/mysql/conf.d`. Use this to add custom tunables or temporarily override the binlog setting without touching the image. - **Drop-in configs** Any `.cnf` placed in `${STORAGE_PATH}/config/mysql/conf.d` (exposed via `MYSQL_CONFIG_DIR`) is mounted into `/etc/mysql/conf.d`. Use this to add custom tunables or temporarily override the binlog setting without touching the image.
### Compose Overrides
All helper scripts automatically include any override file found in `compose-overrides/` when its matching flag `COMPOSE_OVERRIDE_<NAME>_ENABLED` is set to `1` in `.env`. Each override declares its flag at the top with `# override-flag: ...`. This lets you ship opt-in tweaks without editing `docker-compose.yml`.
Current examples:
- `compose-overrides/mysql-expose.yml` (`COMPOSE_OVERRIDE_MYSQL_EXPOSE_ENABLED`) Publishes MySQL to `${MYSQL_EXTERNAL_PORT}` for external clients.
- `compose-overrides/worldserver-debug-logging.yml` (`COMPOSE_OVERRIDE_WORLDSERVER_DEBUG_LOGGING_ENABLED`) Raises `AC_LOG_LEVEL` to `3` across all worldserver profiles for troubleshooting.
Add your own override by dropping a new `.yml` file into `compose-overrides/`, documenting the flag name in a comment, and toggling that flag in `.env`.
### Storage Structure ### Storage Structure
The project uses a dual-storage approach for optimal performance: The project uses a dual-storage approach for optimal performance:
@@ -986,9 +1000,9 @@ Internal script that runs inside the `ac-modules` container to handle module lif
- Manages module configuration files - Manages module configuration files
- Tracks installation state - Tracks installation state
#### `config/modules.json` & `scripts/modules.py` #### `config/module-manifest.json` & `scripts/modules.py`
Central module registry and management system: Central module registry and management system:
- **`config/modules.json`** - Declarative manifest defining all 30+ supported modules with metadata: - **`config/module-manifest.json`** - Declarative manifest defining all 30+ supported modules with metadata:
- Repository URLs - Repository URLs
- Module type (cpp, data, lua) - Module type (cpp, data, lua)
- Build requirements - Build requirements

View File

@@ -114,7 +114,7 @@ generate_module_state(){
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" 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/module-manifest.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
fi fi

View File

@@ -13,6 +13,8 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_DIR="${SCRIPT_DIR}" PROJECT_DIR="${SCRIPT_DIR}"
DEFAULT_COMPOSE_FILE="${PROJECT_DIR}/docker-compose.yml" DEFAULT_COMPOSE_FILE="${PROJECT_DIR}/docker-compose.yml"
ENV_FILE="${PROJECT_DIR}/.env" ENV_FILE="${PROJECT_DIR}/.env"
source "${PROJECT_DIR}/scripts/lib/compose_overrides.sh"
declare -a COMPOSE_FILE_ARGS=()
# Colors # Colors
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; BLUE='\033[0;34m'; MAGENTA='\033[0;35m'; NC='\033[0m' RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; BLUE='\033[0;34m'; MAGENTA='\033[0;35m'; NC='\033[0m'
@@ -125,15 +127,7 @@ if [ -f "$ENV_FILE" ]; then
set -a; source "$ENV_FILE"; set +a set -a; source "$ENV_FILE"; set +a
fi fi
COMPOSE_FILE_ARGS=(-f "$DEFAULT_COMPOSE_FILE") compose_overrides::build_compose_args "$PROJECT_DIR" "$ENV_FILE" "$DEFAULT_COMPOSE_FILE" COMPOSE_FILE_ARGS
if [ "${MYSQL_EXPOSE_PORT:-0}" = "1" ]; then
EXTRA_COMPOSE_FILE="${PROJECT_DIR}/docker-compose.mysql-expose.yml"
if [ -f "$EXTRA_COMPOSE_FILE" ]; then
COMPOSE_FILE_ARGS+=(-f "$EXTRA_COMPOSE_FILE")
else
print_status WARNING "MYSQL_EXPOSE_PORT=1 but $EXTRA_COMPOSE_FILE missing; skipping port exposure override."
fi
fi
COMPOSE_FILE_ARGS_STR="" COMPOSE_FILE_ARGS_STR=""
for arg in "${COMPOSE_FILE_ARGS[@]}"; do for arg in "${COMPOSE_FILE_ARGS[@]}"; do
COMPOSE_FILE_ARGS_STR+=" ${arg}" COMPOSE_FILE_ARGS_STR+=" ${arg}"

View File

@@ -0,0 +1,12 @@
# override-flag: COMPOSE_OVERRIDE_MYSQL_EXPOSE_ENABLED
# legacy-flag: MYSQL_EXPOSE_PORT
# Optional override file that publishes MySQL to the host. Use it only when you
# intentionally need direct access (e.g., external DB clients). RealmMaster scripts
# auto-include this file whenever `COMPOSE_OVERRIDE_MYSQL_EXPOSE_ENABLED=1`
# (or the legacy `MYSQL_EXPOSE_PORT=1`) in `.env`. When running Compose manually, add:
# docker compose -f docker-compose.yml -f compose-overrides/mysql-expose.yml up -d
# Reset the flag to 0 to return to the secure, internal-only default.
services:
ac-mysql:
ports:
- "${MYSQL_EXTERNAL_PORT}:${MYSQL_PORT}"

View File

@@ -0,0 +1,15 @@
# override-flag: COMPOSE_OVERRIDE_WORLDSERVER_DEBUG_LOGGING_ENABLED
# Example override that bumps worldserver log verbosity across all profiles.
# Enable by setting COMPOSE_OVERRIDE_WORLDSERVER_DEBUG_LOGGING_ENABLED=1 in .env.
# Helpful while investigating live issues; remember to turn it off to reduce noise.
# Follow this pattern for any compose layers you want to implement
services:
ac-worldserver-standard:
environment:
AC_LOG_LEVEL: "3"
ac-worldserver-playerbots:
environment:
AC_LOG_LEVEL: "3"
ac-worldserver-modules:
environment:
AC_LOG_LEVEL: "3"

View File

@@ -1,28 +1,39 @@
{ {
"modules": [ "modules": [
"MODULE_ELUNA",
"MODULE_PLAYERBOTS", "MODULE_PLAYERBOTS",
"MODULE_PLAYER_BOT_LEVEL_BRACKETS",
"MODULE_SOLO_LFG",
"MODULE_TRANSMOG",
"MODULE_NPC_BUFFER",
"MODULE_LEARN_SPELLS", "MODULE_LEARN_SPELLS",
"MODULE_FIREWORKS", "MODULE_FIREWORKS",
"MODULE_REAGENT_BANK", "MODULE_TRANSMOG",
"MODULE_BLACK_MARKET_AUCTION_HOUSE", "MODULE_NPC_BUFFER",
"MODULE_SOLO_LFG",
"MODULE_1V1_ARENA", "MODULE_1V1_ARENA",
"MODULE_ACCOUNT_ACHIEVEMENTS",
"MODULE_BREAKING_NEWS", "MODULE_BREAKING_NEWS",
"MODULE_BOSS_ANNOUNCER", "MODULE_BOSS_ANNOUNCER",
"MODULE_ACCOUNT_ACHIEVEMENTS",
"MODULE_AUTO_REVIVE", "MODULE_AUTO_REVIVE",
"MODULE_ELUNA_TS", "MODULE_GAIN_HONOR_GUARD",
"MODULE_ELUNA",
"MODULE_TIME_IS_TIME",
"MODULE_RANDOM_ENCHANTS",
"MODULE_SOLOCRAFT",
"MODULE_NPC_BEASTMASTER", "MODULE_NPC_BEASTMASTER",
"MODULE_NPC_ENCHANTER", "MODULE_NPC_ENCHANTER",
"MODULE_RANDOM_ENCHANTS",
"MODULE_INSTANCE_RESET", "MODULE_INSTANCE_RESET",
"MODULE_TIME_IS_TIME", "MODULE_ARAC",
"MODULE_GAIN_HONOR_GUARD", "MODULE_ASSISTANT",
"MODULE_ARAC" "MODULE_REAGENT_BANK",
"MODULE_BLACK_MARKET_AUCTION_HOUSE",
"MODULE_STATBOOSTER",
"MODULE_ELUNA_TS",
"MODULE_AIO",
"MODULE_ELUNA_SCRIPTS",
"MODULE_EVENT_SCRIPTS",
"MODULE_ACTIVE_CHAT",
"MODULE_GUILDHOUSE",
"MODULE_NPC_FREE_PROFESSIONS",
"MODULE_MORPHSUMMON",
"MODULE_ITEM_LEVEL_UP",
"MODULE_GLOBAL_CHAT"
], ],
"label": "\ud83e\udde9 Sam", "label": "\ud83e\udde9 Sam",
"description": "Sam's playerbot-centric preset (use high bot counts)", "description": "Sam's playerbot-centric preset (use high bot counts)",

View File

@@ -11,6 +11,7 @@ set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
DEFAULT_COMPOSE_FILE="$ROOT_DIR/docker-compose.yml" DEFAULT_COMPOSE_FILE="$ROOT_DIR/docker-compose.yml"
ENV_PATH="$ROOT_DIR/.env" ENV_PATH="$ROOT_DIR/.env"
source "$ROOT_DIR/scripts/lib/compose_overrides.sh"
TARGET_PROFILE="" TARGET_PROFILE=""
WATCH_LOGS=1 WATCH_LOGS=1
KEEP_RUNNING=0 KEEP_RUNNING=0
@@ -280,17 +281,7 @@ read_env(){
} }
init_compose_files(){ init_compose_files(){
local expose_port compose_overrides::build_compose_args "$ROOT_DIR" "$ENV_PATH" "$DEFAULT_COMPOSE_FILE" COMPOSE_FILE_ARGS
expose_port="$(read_env MYSQL_EXPOSE_PORT "0")"
COMPOSE_FILE_ARGS=(-f "$DEFAULT_COMPOSE_FILE")
if [ "$expose_port" = "1" ]; then
local extra_file="$ROOT_DIR/docker-compose.mysql-expose.yml"
if [ -f "$extra_file" ]; then
COMPOSE_FILE_ARGS+=(-f "$extra_file")
else
warn "MYSQL_EXPOSE_PORT=1 but $extra_file not found; skipping port override"
fi
fi
} }
init_compose_files init_compose_files
@@ -337,7 +328,7 @@ ensure_module_state(){
local output_dir="${storage_root}/modules" local output_dir="${storage_root}/modules"
ensure_modules_dir_writable "$storage_root" 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/module-manifest.json" generate --output-dir "$output_dir"; then
err "Module manifest validation failed. See errors above." err "Module manifest validation failed. See errors above."
fi fi

View File

@@ -1,5 +0,0 @@
services:
ac-mysql:
# Optional override that publishes the MySQL port when MYSQL_EXPOSE_PORT=1
ports:
- "${MYSQL_EXTERNAL_PORT}:${MYSQL_PORT}"

View File

@@ -596,7 +596,7 @@ services:
env_file: env_file:
- ./.env - ./.env
environment: environment:
MODULES_MANIFEST_PATH: /tmp/config/modules.json MODULES_MANIFEST_PATH: /tmp/config/module-manifest.json
entrypoint: ["/bin/sh"] entrypoint: ["/bin/sh"]
command: command:
- -c - -c

View File

@@ -14,9 +14,27 @@ This guide mirrors the community “Installing AzerothCore using Docker” workf
RealmMaster keeps the familiar `docker-compose.yml` at the repo root. Instead of editing the YAML directly, run `./setup.sh` (see [README → Getting Started](../README.md#getting-started)) to generate `.env`; every setting from storage paths and ports to module toggles lives there. This mirrors the upstream “use docker-compose.override.yml” advice while preserving a single declarative stack. RealmMaster keeps the familiar `docker-compose.yml` at the repo root. Instead of editing the YAML directly, run `./setup.sh` (see [README → Getting Started](../README.md#getting-started)) to generate `.env`; every setting from storage paths and ports to module toggles lives there. This mirrors the upstream “use docker-compose.override.yml” advice while preserving a single declarative stack.
- **Security**: databases stay on the internal `azerothcore` bridge and never publish MySQL ports unless you explicitly set `MYSQL_EXPOSE_PORT` in `.env`. Binary logging is disabled via `MYSQL_DISABLE_BINLOG=1`, matching the upstream recommendation for playerbots. - **Security**: databases stay on the internal `azerothcore` bridge and never publish MySQL ports unless you explicitly set `COMPOSE_OVERRIDE_MYSQL_EXPOSE_ENABLED=1` in `.env`. Binary logging is disabled via `MYSQL_DISABLE_BINLOG=1`, matching the upstream recommendation for playerbots.
- **Storage**: bind mounts map to `storage/` and `local-storage/`, ensuring data survives container rebuilds just like the original bind-mount instructions. `ac-volume-init` and `ac-storage-init` bootstrap ownership so you do not need to chown paths manually. - **Storage**: bind mounts map to `storage/` and `local-storage/`, ensuring data survives container rebuilds just like the original bind-mount instructions. `ac-volume-init` and `ac-storage-init` bootstrap ownership so you do not need to chown paths manually.
- **Networks & profiles**: all services share the `azerothcore` bridge, and Compose profiles (`services-standard`, `services-playerbots`, `services-modules`, `tools`) let you enable only what you need, similar to copying multiple override files upstream. - **Networks & profiles**: all services share the `azerothcore` bridge, and Compose profiles (`services-standard`, `services-playerbots`, `services-modules`, `tools`) let you enable only what you need, similar to copying multiple override files upstream.
- **Override toggles**: drop-in files under `compose-overrides/` (like `mysql-expose.yml` for port exposure or `worldserver-debug-logging.yml` for verbose logs) can be activated by setting `COMPOSE_OVERRIDE_<NAME>_ENABLED=1` in `.env`, so you can extend the stack without editing the main compose file.
- **Module manifest**: all module metadata lives in `config/module-manifest.json`; presets surfaced in `setup.sh` come from `config/module-profiles/*.json`, so you can adapt the same workflow the upstream document used by editing those files.
### Override Examples
RealmMaster ships with two opt-in overrides to demonstrate the pattern:
- `compose-overrides/mysql-expose.yml` (`COMPOSE_OVERRIDE_MYSQL_EXPOSE_ENABLED=1`) publishes MySQL on `${MYSQL_EXTERNAL_PORT}` for IDEs or external tooling.
- `compose-overrides/worldserver-debug-logging.yml` (`COMPOSE_OVERRIDE_WORLDSERVER_DEBUG_LOGGING_ENABLED=1`) bumps `AC_LOG_LEVEL` to `3` across every worldserver profile for troubleshooting.
Add your own overrides by dropping a `.yml` file into `compose-overrides/` with a `# override-flag: ...` header and toggling the matching env flag. All project scripts automatically include enabled overrides, so the workflow mirrors the upstream “override file” approach without manual compose arguments.
### Module Layout
- **Manifest**: `config/module-manifest.json` tracks every supported module (type, repo, dependencies). Edit this if you need to add or update modules—`scripts/modules.py` and all container helpers consume it automatically.
- **Presets**: `config/module-profiles/*.json` replaces the old `profiles/*.json`. Each preset defines a `modules` list plus optional `label/description/order`, and `setup.sh` surfaces them in the module-selection menu or via `--module-config <name>`.
Because the manifest/preset locations mirror the upstream structure conceptually, experienced users can jump straight into editing those files without re-learning the workflow.
Example excerpt (trimmed for clarity): Example excerpt (trimmed for clarity):

View File

@@ -8,7 +8,7 @@ from pathlib import Path
def load_module_state(root: Path) -> dict: def load_module_state(root: Path) -> dict:
env_path = root / ".env" env_path = root / ".env"
manifest_path = root / "config" / "modules.json" manifest_path = root / "config" / "module-manifest.json"
modules_py = root / "scripts" / "modules.py" modules_py = root / "scripts" / "modules.py"
try: try:

View File

@@ -7,6 +7,7 @@ set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/.." ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/.."
DEFAULT_COMPOSE_FILE="$ROOT_DIR/docker-compose.yml" DEFAULT_COMPOSE_FILE="$ROOT_DIR/docker-compose.yml"
ENV_FILE="$ROOT_DIR/.env" ENV_FILE="$ROOT_DIR/.env"
source "$ROOT_DIR/scripts/lib/compose_overrides.sh"
declare -a COMPOSE_FILE_ARGS=() declare -a COMPOSE_FILE_ARGS=()
BLUE='\033[0;34m' BLUE='\033[0;34m'
@@ -46,15 +47,7 @@ resolve_project_name(){
} }
init_compose_files(){ init_compose_files(){
COMPOSE_FILE_ARGS=(-f "$DEFAULT_COMPOSE_FILE") compose_overrides::build_compose_args "$ROOT_DIR" "$ENV_FILE" "$DEFAULT_COMPOSE_FILE" COMPOSE_FILE_ARGS
if [ "$(read_env MYSQL_EXPOSE_PORT "0")" = "1" ]; then
local extra_file="$ROOT_DIR/docker-compose.mysql-expose.yml"
if [ -f "$extra_file" ]; then
COMPOSE_FILE_ARGS+=(-f "$extra_file")
else
warn "MYSQL_EXPOSE_PORT=1 but $extra_file missing; skipping port override."
fi
fi
} }
init_compose_files init_compose_files

View File

@@ -1,49 +0,0 @@
# Post-Install Hooks Refactoring Summary
## What Was Accomplished
### 1. **Legacy System Issues**
- Hardcoded hooks in `manage-modules.sh` (only 2 implemented)
- 26 undefined hooks from Eluna modules causing warnings
- No extensibility or maintainability
### 2. **New Architecture Implemented**
#### **External Hook Scripts** (`scripts/hooks/`)
- `copy-standard-lua` - Generic Lua script copying for Eluna modules
- `copy-aio-lua` - AIO-specific Lua script handling
- `mod-ale-patches` - mod-ale compatibility patches
- `black-market-setup` - Black Market specific setup
- `README.md` - Complete documentation
#### **Manifest-Driven Configuration**
- All hooks now defined in `config/modules.json`
- Standardized hook names (kebab-case)
- No more undefined hooks
#### **Refactored Hook Runner** (`manage-modules.sh`)
- External script execution with environment variables
- Proper error handling (exit codes 0/1/2)
- Environment cleanup
- Removed legacy fallback code
### 3. **Hook Mapping Applied**
- **24 Eluna modules** → `copy-standard-lua`
- **2 AIO modules** → `copy-aio-lua`
- **1 mod-ale module** → `mod-ale-patches`
- **1 Black Market module** → `black-market-setup`
### 4. **Benefits Achieved**
-**Maintainable** - Hooks are separate, reusable scripts
-**Extensible** - Easy to add new hooks without code changes
-**Reliable** - No more undefined hook warnings
-**Documented** - Clear interface and usage patterns
-**Clean** - Removed legacy code and hardcoded cases
## Files Modified
- `scripts/hooks/` (new directory with 5 files)
- `scripts/manage-modules.sh` (refactored hook runner)
- `config/modules.json` (updated all 28 hook definitions)
## Testing Ready
The system is ready for testing with the modules container to ensure all Lua scripts are properly copied to `/azerothcore/lua_scripts` during module installation.

View File

@@ -0,0 +1,101 @@
#!/usr/bin/env bash
# Helper utilities for dynamically including docker compose override files
# based on FEATURE_NAME_ENABLED style environment flags.
compose_overrides::trim() {
local value="$1"
# shellcheck disable=SC2001
value="$(echo "$value" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
printf '%s' "$value"
}
compose_overrides::derive_flag_from_name() {
local file="$1"
local base
base="$(basename "$file")"
base="${base%.*}"
base="${base//[^[:alnum:]]/_}"
base="${base^^}"
printf 'COMPOSE_OVERRIDE_%s_ENABLED' "$base"
}
compose_overrides::extract_tag() {
local file="$1" tag="$2"
local line
line="$(grep -m1 "^# *${tag}:" "$file" 2>/dev/null || true)"
if [ -z "$line" ]; then
return 1
fi
line="${line#*:}"
compose_overrides::trim "$line"
}
compose_overrides::extract_all_tags() {
local file="$1" tag="$2"
grep "^# *${tag}:" "$file" 2>/dev/null | cut -d':' -f2- | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//'
}
compose_overrides::read_env_value() {
local env_path="$1" key="$2" default="${3:-}"
local value=""
if [ -f "$env_path" ]; then
value="$(grep -E "^${key}=" "$env_path" | tail -n1 | cut -d'=' -f2- | tr -d '\r')"
fi
if [ -z "$value" ]; then
value="$default"
fi
printf '%s' "$value"
}
compose_overrides::list_enabled_files() {
local root_dir="$1" env_path="$2" result_var="$3"
local overrides_dir="${root_dir}/compose-overrides"
local -n __result="$result_var"
__result=()
[ -d "$overrides_dir" ] || return 0
local -a override_files=()
while IFS= read -r -d '' file; do
override_files+=("$file")
done < <(find "$overrides_dir" -maxdepth 1 -type f \( -name '*.yml' -o -name '*.yaml' \) -print0 | sort -z)
local file flag flag_value legacy_default legacy_flags legacy_flag
for file in "${override_files[@]}"; do
flag="$(compose_overrides::extract_tag "$file" "override-flag" || true)"
if [ -z "$flag" ]; then
flag="$(compose_overrides::derive_flag_from_name "$file")"
fi
legacy_default="0"
legacy_flags="$(compose_overrides::extract_all_tags "$file" "legacy-flag" || true)"
if [ -n "$legacy_flags" ]; then
while IFS= read -r legacy_flag; do
[ -z "$legacy_flag" ] && continue
legacy_default="$(compose_overrides::read_env_value "$env_path" "$legacy_flag" "$legacy_default")"
# Stop at first legacy flag that yields a value
if [ -n "$legacy_default" ]; then
break
fi
done <<< "$legacy_flags"
fi
flag_value="$(compose_overrides::read_env_value "$env_path" "$flag" "$legacy_default")"
if [ "$flag_value" = "1" ]; then
__result+=("$file")
fi
done
}
compose_overrides::build_compose_args() {
local root_dir="$1" env_path="$2" default_compose="$3" result_var="$4"
local -n __result="$result_var"
__result=(-f "$default_compose")
local -a enabled_files=()
compose_overrides::list_enabled_files "$root_dir" "$env_path" enabled_files
for file in "${enabled_files[@]}"; do
__result+=(-f "$file")
done
}

View File

@@ -130,7 +130,7 @@ ensure_module_metadata(){
fi fi
done done
local manifest_path="${MANIFEST_PATH:-${MODULES_MANIFEST_PATH:-/tmp/config/modules.json}}" local manifest_path="${MANIFEST_PATH:-${MODULES_MANIFEST_PATH:-/tmp/config/module-manifest.json}}"
local env_path="${ENV_PATH:-${MODULES_ENV_PATH:-/tmp/.env}}" local env_path="${ENV_PATH:-${MODULES_ENV_PATH:-/tmp/.env}}"
local state_env_candidate="${STATE_DIR:-${MODULES_ROOT:-/modules}}/modules.env" local state_env_candidate="${STATE_DIR:-${MODULES_ROOT:-/modules}}/modules.env"
if [ -f "$state_env_candidate" ]; then if [ -f "$state_env_candidate" ]; then

View File

@@ -55,22 +55,22 @@ resolve_manifest_path(){
return return
fi fi
local candidate local candidate
candidate="$PROJECT_ROOT/config/modules.json" candidate="$PROJECT_ROOT/config/module-manifest.json"
if [ -f "$candidate" ]; then if [ -f "$candidate" ]; then
echo "$candidate" echo "$candidate"
return return
fi fi
candidate="$SCRIPT_DIR/../config/modules.json" candidate="$SCRIPT_DIR/../config/module-manifest.json"
if [ -f "$candidate" ]; then if [ -f "$candidate" ]; then
echo "$candidate" echo "$candidate"
return return
fi fi
candidate="/tmp/config/modules.json" candidate="/tmp/config/module-manifest.json"
if [ -f "$candidate" ]; then if [ -f "$candidate" ]; then
echo "$candidate" echo "$candidate"
return return
fi fi
err "Unable to locate module manifest (set MODULES_MANIFEST_PATH or ensure config/modules.json exists)" err "Unable to locate module manifest (set MODULES_MANIFEST_PATH or ensure config/module-manifest.json exists)"
} }
setup_git_config(){ setup_git_config(){

View File

@@ -2,7 +2,7 @@
""" """
Module manifest helper. Module manifest helper.
Reads config/modules.json and .env to produce canonical module state that Reads config/module-manifest.json and .env to produce canonical module state that
downstream shell scripts can consume for staging, rebuild detection, and downstream shell scripts can consume for staging, rebuild detection, and
dependency validation. dependency validation.
""" """
@@ -466,8 +466,8 @@ def configure_parser() -> argparse.ArgumentParser:
) )
parser.add_argument( parser.add_argument(
"--manifest", "--manifest",
default="config/modules.json", default="config/module-manifest.json",
help="Path to module manifest (default: config/modules.json)", help="Path to module manifest (default: config/module-manifest.json)",
) )
subparsers = parser.add_subparsers(dest="command", required=True) subparsers = parser.add_subparsers(dest="command", required=True)

View File

@@ -179,7 +179,7 @@ ensure_module_state(){
local storage_root local storage_root
storage_root="$(resolve_local_storage_path)" storage_root="$(resolve_local_storage_path)"
MODULE_STATE_DIR="${storage_root}/modules" MODULE_STATE_DIR="${storage_root}/modules"
if ! python3 "$MODULE_HELPER" --env-path "$ENV_FILE" --manifest "$PROJECT_DIR/config/modules.json" generate --output-dir "$MODULE_STATE_DIR"; then if ! python3 "$MODULE_HELPER" --env-path "$ENV_FILE" --manifest "$PROJECT_DIR/config/module-manifest.json" generate --output-dir "$MODULE_STATE_DIR"; then
echo "❌ Module manifest validation failed. See details above." echo "❌ Module manifest validation failed. See details above."
exit 1 exit 1
fi fi
@@ -463,7 +463,7 @@ remove_sentinel(){
fi fi
if command -v docker >/dev/null 2>&1; then if command -v docker >/dev/null 2>&1; then
local db_image local db_image
db_image="$(read_env AC_DB_IMPORT_IMAGE "acore/ac-wotlk-db-import:14.0.0-dev")" db_image="$(read_env AC_DB_IMPORT_IMAGE "acore/ac-wotlk-db-import:master")"
if docker image inspect "$db_image" >/dev/null 2>&1; then if docker image inspect "$db_image" >/dev/null 2>&1; then
local mount_dir local mount_dir
mount_dir="$(dirname "$sentinel_path")" mount_dir="$(dirname "$sentinel_path")"

View File

@@ -65,7 +65,7 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_DIR="$(dirname "$SCRIPT_DIR")" PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
ENV_FILE="$PROJECT_DIR/.env" ENV_FILE="$PROJECT_DIR/.env"
DEFAULT_COMPOSE_FILE="$PROJECT_DIR/docker-compose.yml" DEFAULT_COMPOSE_FILE="$PROJECT_DIR/docker-compose.yml"
EXTRA_COMPOSE_FILE="$PROJECT_DIR/docker-compose.mysql-expose.yml" source "$PROJECT_DIR/scripts/lib/compose_overrides.sh"
usage(){ usage(){
cat <<EOF cat <<EOF
@@ -116,12 +116,10 @@ resolve_project_name(){
if [ -z "${COMPOSE_FILE:-}" ]; then if [ -z "${COMPOSE_FILE:-}" ]; then
compose_files=("$DEFAULT_COMPOSE_FILE") compose_files=("$DEFAULT_COMPOSE_FILE")
if [ "$(read_env MYSQL_EXPOSE_PORT "0")" = "1" ]; then declare -a enabled_overrides=()
if [ -f "$EXTRA_COMPOSE_FILE" ]; then compose_overrides::list_enabled_files "$PROJECT_DIR" "$ENV_FILE" enabled_overrides
compose_files+=("$EXTRA_COMPOSE_FILE") if [ "${#enabled_overrides[@]}" -gt 0 ]; then
else compose_files+=("${enabled_overrides[@]}")
echo "⚠️ MYSQL_EXPOSE_PORT=1 but ${EXTRA_COMPOSE_FILE} not found; continuing without port exposure override."
fi
fi fi
COMPOSE_FILE="$(IFS=:; echo "${compose_files[*]}")" COMPOSE_FILE="$(IFS=:; echo "${compose_files[*]}")"
export COMPOSE_FILE export COMPOSE_FILE

View File

@@ -15,7 +15,7 @@ from pathlib import Path
root = Path(sys.argv[1]) root = Path(sys.argv[1])
modules_py = root / "scripts" / "modules.py" modules_py = root / "scripts" / "modules.py"
env_path = root / ".env" env_path = root / ".env"
manifest_path = root / "config" / "modules.json" manifest_path = root / "config" / "module-manifest.json"
state = json.loads(subprocess.check_output([ state = json.loads(subprocess.check_output([
sys.executable, sys.executable,

View File

@@ -13,6 +13,7 @@ err(){ echo -e "${RED}❌ $*${NC}"; }
PROJECT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" PROJECT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
COMPOSE_FILE="$PROJECT_DIR/docker-compose.yml" COMPOSE_FILE="$PROJECT_DIR/docker-compose.yml"
ENV_FILE="" ENV_FILE=""
source "$PROJECT_DIR/scripts/lib/compose_overrides.sh"
PROFILES=(db services-standard client-data modules tools) PROFILES=(db services-standard client-data modules tools)
SKIP_DEPLOY=false SKIP_DEPLOY=false
QUICK=false QUICK=false
@@ -73,15 +74,13 @@ run_compose(){
compose_args+=(--env-file "$ENV_FILE") compose_args+=(--env-file "$ENV_FILE")
fi fi
compose_args+=(-f "$COMPOSE_FILE") compose_args+=(-f "$COMPOSE_FILE")
if [ "$(read_env_value MYSQL_EXPOSE_PORT "0")" = "1" ]; then local env_path
local extra_file env_path="$(env_file_path)"
extra_file="$(dirname "$COMPOSE_FILE")/docker-compose.mysql-expose.yml" declare -a enabled_overrides=()
if [ -f "$extra_file" ]; then compose_overrides::list_enabled_files "$PROJECT_DIR" "$env_path" enabled_overrides
compose_args+=(-f "$extra_file") for file in "${enabled_overrides[@]}"; do
else compose_args+=(-f "$file")
warn "MYSQL_EXPOSE_PORT=1 but ${extra_file} missing; skipping port exposure override." done
fi
fi
docker compose "${compose_args[@]}" "$@" docker compose "${compose_args[@]}" "$@"
} }

View File

@@ -68,11 +68,12 @@ declare -A TEMPLATE_VALUE_MAP=(
[DEFAULT_AUTH_PORT]=AUTH_EXTERNAL_PORT [DEFAULT_AUTH_PORT]=AUTH_EXTERNAL_PORT
[DEFAULT_SOAP_PORT]=SOAP_EXTERNAL_PORT [DEFAULT_SOAP_PORT]=SOAP_EXTERNAL_PORT
[DEFAULT_MYSQL_PORT]=MYSQL_EXTERNAL_PORT [DEFAULT_MYSQL_PORT]=MYSQL_EXTERNAL_PORT
[DEFAULT_MYSQL_EXPOSE_PORT]=MYSQL_EXPOSE_PORT
[DEFAULT_PLAYERBOT_MIN]=PLAYERBOT_MIN_BOTS [DEFAULT_PLAYERBOT_MIN]=PLAYERBOT_MIN_BOTS
[DEFAULT_PLAYERBOT_MAX]=PLAYERBOT_MAX_BOTS [DEFAULT_PLAYERBOT_MAX]=PLAYERBOT_MAX_BOTS
[DEFAULT_LOCAL_STORAGE]=STORAGE_PATH [DEFAULT_LOCAL_STORAGE]=STORAGE_PATH
[DEFAULT_BACKUP_PATH]=BACKUP_PATH [DEFAULT_BACKUP_PATH]=BACKUP_PATH
[DEFAULT_COMPOSE_OVERRIDE_MYSQL_EXPOSE_ENABLED]=COMPOSE_OVERRIDE_MYSQL_EXPOSE_ENABLED
[DEFAULT_COMPOSE_OVERRIDE_WORLDSERVER_DEBUG_LOGGING_ENABLED]=COMPOSE_OVERRIDE_WORLDSERVER_DEBUG_LOGGING_ENABLED
[PERMISSION_LOCAL_USER]=DEFAULT_PERMISSION_LOCAL_USER [PERMISSION_LOCAL_USER]=DEFAULT_PERMISSION_LOCAL_USER
[PERMISSION_NFS_USER]=DEFAULT_PERMISSION_NFS_USER [PERMISSION_NFS_USER]=DEFAULT_PERMISSION_NFS_USER
[DEFAULT_CUSTOM_UID]=DEFAULT_CUSTOM_UID [DEFAULT_CUSTOM_UID]=DEFAULT_CUSTOM_UID
@@ -351,7 +352,7 @@ EOF
# Module metadata / defaults # Module metadata / defaults
# ============================== # ==============================
MODULE_MANIFEST_PATH="$SCRIPT_DIR/config/modules.json" MODULE_MANIFEST_PATH="$SCRIPT_DIR/config/module-manifest.json"
MODULE_MANIFEST_HELPER="$SCRIPT_DIR/scripts/setup_manifest.py" MODULE_MANIFEST_HELPER="$SCRIPT_DIR/scripts/setup_manifest.py"
MODULE_PROFILES_HELPER="$SCRIPT_DIR/scripts/setup_profiles.py" MODULE_PROFILES_HELPER="$SCRIPT_DIR/scripts/setup_profiles.py"
ENV_TEMPLATE_FILE="$SCRIPT_DIR/.env.template" ENV_TEMPLATE_FILE="$SCRIPT_DIR/.env.template"
@@ -576,7 +577,7 @@ Options:
--backup-retention-hours N Hourly backup retention (default 6) --backup-retention-hours N Hourly backup retention (default 6)
--backup-daily-time HH Daily backup hour 00-23 (default 09) --backup-daily-time HH Daily backup hour 00-23 (default 09)
--module-mode MODE suggested, playerbots, manual, or none --module-mode MODE suggested, playerbots, manual, or none
--module-config NAME Use preset NAME from profiles/<NAME>.json --module-config NAME Use preset NAME from config/module-profiles/<NAME>.json
--enable-modules LIST Comma-separated module list (MODULE_* or shorthand) --enable-modules LIST Comma-separated module list (MODULE_* or shorthand)
--playerbot-enabled 0|1 Override PLAYERBOT_ENABLED flag --playerbot-enabled 0|1 Override PLAYERBOT_ENABLED flag
--playerbot-min-bots N Override PLAYERBOT_MIN_BOTS value --playerbot-min-bots N Override PLAYERBOT_MIN_BOTS value
@@ -935,7 +936,7 @@ fi
declare -A MODULE_PRESET_LABELS=() declare -A MODULE_PRESET_LABELS=()
declare -A MODULE_PRESET_DESCRIPTIONS=() declare -A MODULE_PRESET_DESCRIPTIONS=()
declare -A MODULE_PRESET_ORDER=() declare -A MODULE_PRESET_ORDER=()
local CONFIG_DIR="$SCRIPT_DIR/profiles" local CONFIG_DIR="$SCRIPT_DIR/config/module-profiles"
if [ ! -x "$MODULE_PROFILES_HELPER" ]; then if [ ! -x "$MODULE_PROFILES_HELPER" ]; then
say ERROR "Profile helper not found or not executable at $MODULE_PROFILES_HELPER" say ERROR "Profile helper not found or not executable at $MODULE_PROFILES_HELPER"
exit 1 exit 1
@@ -953,7 +954,7 @@ fi
local missing_presets=0 local missing_presets=0
for required_preset in "$DEFAULT_PRESET_SUGGESTED" "$DEFAULT_PRESET_PLAYERBOTS"; do for required_preset in "$DEFAULT_PRESET_SUGGESTED" "$DEFAULT_PRESET_PLAYERBOTS"; do
if [ -z "${MODULE_PRESET_CONFIGS[$required_preset]:-}" ]; then if [ -z "${MODULE_PRESET_CONFIGS[$required_preset]:-}" ]; then
say ERROR "Missing module preset profiles/${required_preset}.json" say ERROR "Missing module preset config/module-profiles/${required_preset}.json"
missing_presets=1 missing_presets=1
fi fi
done done
@@ -1036,7 +1037,7 @@ fi
else else
pretty_name=$(echo "$preset_name" | tr '_-' ' ' | awk '{for(i=1;i<=NF;i++){$i=toupper(substr($i,1,1)) substr($i,2)}}1') pretty_name=$(echo "$preset_name" | tr '_-' ' ' | awk '{for(i=1;i<=NF;i++){$i=toupper(substr($i,1,1)) substr($i,2)}}1')
fi fi
echo "${menu_index}) ${pretty_name} (profiles/${preset_name}.json)" echo "${menu_index}) ${pretty_name} (config/module-profiles/${preset_name}.json)"
MENU_PRESET_INDEX[$menu_index]="$preset_name" MENU_PRESET_INDEX[$menu_index]="$preset_name"
menu_index=$((menu_index + 1)) menu_index=$((menu_index + 1))
done done
@@ -1454,7 +1455,8 @@ fi
HOST_ZONEINFO_PATH=${HOST_ZONEINFO_PATH:-$DEFAULT_HOST_ZONEINFO_PATH} HOST_ZONEINFO_PATH=${HOST_ZONEINFO_PATH:-$DEFAULT_HOST_ZONEINFO_PATH}
MYSQL_INNODB_REDO_LOG_CAPACITY=${MYSQL_INNODB_REDO_LOG_CAPACITY:-$DEFAULT_MYSQL_INNODB_REDO_LOG_CAPACITY} MYSQL_INNODB_REDO_LOG_CAPACITY=${MYSQL_INNODB_REDO_LOG_CAPACITY:-$DEFAULT_MYSQL_INNODB_REDO_LOG_CAPACITY}
MYSQL_RUNTIME_TMPFS_SIZE=${MYSQL_RUNTIME_TMPFS_SIZE:-$DEFAULT_MYSQL_RUNTIME_TMPFS_SIZE} MYSQL_RUNTIME_TMPFS_SIZE=${MYSQL_RUNTIME_TMPFS_SIZE:-$DEFAULT_MYSQL_RUNTIME_TMPFS_SIZE}
MYSQL_EXPOSE_PORT=${MYSQL_EXPOSE_PORT:-$DEFAULT_MYSQL_EXPOSE_PORT} COMPOSE_OVERRIDE_MYSQL_EXPOSE_ENABLED=${COMPOSE_OVERRIDE_MYSQL_EXPOSE_ENABLED:-$DEFAULT_COMPOSE_OVERRIDE_MYSQL_EXPOSE_ENABLED}
COMPOSE_OVERRIDE_WORLDSERVER_DEBUG_LOGGING_ENABLED=${COMPOSE_OVERRIDE_WORLDSERVER_DEBUG_LOGGING_ENABLED:-$DEFAULT_COMPOSE_OVERRIDE_WORLDSERVER_DEBUG_LOGGING_ENABLED}
MYSQL_DISABLE_BINLOG=${MYSQL_DISABLE_BINLOG:-$DEFAULT_MYSQL_DISABLE_BINLOG} MYSQL_DISABLE_BINLOG=${MYSQL_DISABLE_BINLOG:-$DEFAULT_MYSQL_DISABLE_BINLOG}
MYSQL_CONFIG_DIR=${MYSQL_CONFIG_DIR:-$DEFAULT_MYSQL_CONFIG_DIR} MYSQL_CONFIG_DIR=${MYSQL_CONFIG_DIR:-$DEFAULT_MYSQL_CONFIG_DIR}
CLIENT_DATA_PATH=${CLIENT_DATA_PATH:-$DEFAULT_CLIENT_DATA_PATH} CLIENT_DATA_PATH=${CLIENT_DATA_PATH:-$DEFAULT_CLIENT_DATA_PATH}
@@ -1502,6 +1504,12 @@ fi
cat <<EOF cat <<EOF
# Generated by ac-compose/setup.sh # Generated by ac-compose/setup.sh
# Compose overrides (set to 1 to include matching file under compose-overrides/)
# mysql-expose.yml -> exposes MySQL externally via COMPOSE_OVERRIDE_MYSQL_EXPOSE_ENABLED
# worldserver-debug-logging.yml -> raises log verbosity via COMPOSE_OVERRIDE_WORLDSERVER_DEBUG_LOGGING_ENABLED
COMPOSE_OVERRIDE_MYSQL_EXPOSE_ENABLED=$COMPOSE_OVERRIDE_MYSQL_EXPOSE_ENABLED
COMPOSE_OVERRIDE_WORLDSERVER_DEBUG_LOGGING_ENABLED=$COMPOSE_OVERRIDE_WORLDSERVER_DEBUG_LOGGING_ENABLED
COMPOSE_PROJECT_NAME=$DEFAULT_COMPOSE_PROJECT_NAME COMPOSE_PROJECT_NAME=$DEFAULT_COMPOSE_PROJECT_NAME
STORAGE_PATH=$STORAGE_PATH STORAGE_PATH=$STORAGE_PATH
@@ -1516,7 +1524,6 @@ MYSQL_ROOT_HOST=$DEFAULT_MYSQL_ROOT_HOST
MYSQL_USER=$DEFAULT_MYSQL_USER MYSQL_USER=$DEFAULT_MYSQL_USER
MYSQL_PORT=$DEFAULT_MYSQL_INTERNAL_PORT MYSQL_PORT=$DEFAULT_MYSQL_INTERNAL_PORT
MYSQL_EXTERNAL_PORT=$MYSQL_EXTERNAL_PORT MYSQL_EXTERNAL_PORT=$MYSQL_EXTERNAL_PORT
MYSQL_EXPOSE_PORT=${MYSQL_EXPOSE_PORT:-$DEFAULT_MYSQL_EXPOSE_PORT}
MYSQL_DISABLE_BINLOG=${MYSQL_DISABLE_BINLOG:-$DEFAULT_MYSQL_DISABLE_BINLOG} MYSQL_DISABLE_BINLOG=${MYSQL_DISABLE_BINLOG:-$DEFAULT_MYSQL_DISABLE_BINLOG}
MYSQL_CONFIG_DIR=${MYSQL_CONFIG_DIR:-$DEFAULT_MYSQL_CONFIG_DIR} MYSQL_CONFIG_DIR=${MYSQL_CONFIG_DIR:-$DEFAULT_MYSQL_CONFIG_DIR}
MYSQL_CHARACTER_SET=$DEFAULT_MYSQL_CHARACTER_SET MYSQL_CHARACTER_SET=$DEFAULT_MYSQL_CHARACTER_SET

View File

@@ -53,7 +53,7 @@ AUTH_PORT="$(read_env AUTH_EXTERNAL_PORT)"
WORLD_PORT="$(read_env WORLD_EXTERNAL_PORT)" WORLD_PORT="$(read_env WORLD_EXTERNAL_PORT)"
SOAP_PORT="$(read_env SOAP_EXTERNAL_PORT)" SOAP_PORT="$(read_env SOAP_EXTERNAL_PORT)"
MYSQL_PORT="$(read_env MYSQL_EXTERNAL_PORT)" MYSQL_PORT="$(read_env MYSQL_EXTERNAL_PORT)"
MYSQL_EXPOSE_PORT="$(read_env MYSQL_EXPOSE_PORT)" MYSQL_EXPOSE_OVERRIDE="$(read_env COMPOSE_OVERRIDE_MYSQL_EXPOSE_ENABLED "$(read_env MYSQL_EXPOSE_PORT "0")")"
PMA_PORT="$(read_env PMA_EXTERNAL_PORT)" PMA_PORT="$(read_env PMA_EXTERNAL_PORT)"
KEIRA_PORT="$(read_env KEIRA3_EXTERNAL_PORT)" KEIRA_PORT="$(read_env KEIRA3_EXTERNAL_PORT)"
ELUNA_ENABLED="$(read_env AC_ELUNA_ENABLED)" ELUNA_ENABLED="$(read_env AC_ELUNA_ENABLED)"
@@ -255,7 +255,7 @@ ports_summary(){
for i in "${!names[@]}"; do for i in "${!names[@]}"; do
local svc="${names[$i]}" local svc="${names[$i]}"
local port="${ports[$i]}" local port="${ports[$i]}"
if [ "$svc" = "MySQL" ] && [ "${MYSQL_EXPOSE_PORT}" != "1" ]; then if [ "$svc" = "MySQL" ] && [ "${MYSQL_EXPOSE_OVERRIDE}" != "1" ]; then
printf " %-10s %-6s %b○%b not exposed\n" "$svc" "--" "$CYAN" "$NC" printf " %-10s %-6s %b○%b not exposed\n" "$svc" "--" "$CYAN" "$NC"
continue continue
fi fi