diff options
author | Yehonal <yehonal.azeroth@gmail.com> | 2025-07-01 15:35:54 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-07-01 15:35:54 +0200 |
commit | e1b2689c3a2b1395323d2fc58588b1e1b3c07c53 (patch) | |
tree | f36a888ec1fef286ac59607c8a513668286e4065 /apps/startup-scripts/src/run-engine | |
parent | d3130f0d39064d03bed969c7bc135ebb6066442f (diff) |
feat(bash): startup-scripts reworked + bash scripts workflow integration (#22401)
Diffstat (limited to 'apps/startup-scripts/src/run-engine')
-rwxr-xr-x | apps/startup-scripts/src/run-engine | 467 |
1 files changed, 467 insertions, 0 deletions
diff --git a/apps/startup-scripts/src/run-engine b/apps/startup-scripts/src/run-engine new file mode 100755 index 0000000000..2860339a5e --- /dev/null +++ b/apps/startup-scripts/src/run-engine @@ -0,0 +1,467 @@ +#!/usr/bin/env bash + +# AzerothCore Run Engine +# Advanced script for running AzerothCore services with session management and restart capabilities +# +# This script can be sourced to provide functions or executed directly with parameters +# +# Configuration Priority Order (highest to lowest): +# 1. conf.sh - User configuration file (highest priority) +# 2. Command line arguments (--config, --server-config, etc.) +# 3. Environment variables (RUN_ENGINE_*) +# 4. conf.sh.dist - Default configuration (lowest priority) +# +# Environment Variables: +# RUN_ENGINE_CONFIG_FILE - Path to temporary configuration file (optional) +# RUN_ENGINE_SESSION_MANAGER - Session manager (none|auto|tmux|screen, default: auto) +# RUN_ENGINE_BINPATH - Binary directory path +# RUN_ENGINE_SERVERBIN - Server binary name (worldserver|authserver) +# RUN_ENGINE_CONFIG - Server configuration file path +# RUN_ENGINE_LOGS_PATH - Directory for log files +# RUN_ENGINE_CRASHES_PATH - Directory for crash dumps +# RUN_ENGINE_SESSION_NAME - Session name for tmux/screen + +export RUN_ENGINE_PATH="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +# Configuration priority order: +# 1. conf.sh (highest priority - user overrides) +# 2. Environment variables (RUN_ENGINE_*) +# 3. conf.sh.dist (lowest priority - defaults) + +# Load default configuration first (sets defaults from environment variables) +if [ -e "$RUN_ENGINE_PATH/conf.sh.dist" ]; then + source "$RUN_ENGINE_PATH/conf.sh.dist" +fi + +# Load user configuration if exists (this takes priority over everything) +if [ -e "$RUN_ENGINE_PATH/conf.sh" ]; then + source "$RUN_ENGINE_PATH/conf.sh" +fi + +# Load configuration +function load_config() { + local config_file="$1" + + # If a specific config file is provided via command line, load it + # This allows temporary overrides for specific runs + if [ -n "$config_file" ] && [ -e "$config_file" ]; then + echo "Loading configuration from: $config_file" + source "$config_file" + elif [ -n "$RUN_ENGINE_CONFIG_FILE" ] && [ -e "$RUN_ENGINE_CONFIG_FILE" ]; then + echo "Loading configuration from environment: $RUN_ENGINE_CONFIG_FILE" + source "$RUN_ENGINE_CONFIG_FILE" + fi + + # Final override with any remaining environment variables + # This ensures that even after loading config files, environment variables take precedence + BINPATH="${RUN_ENGINE_BINPATH:-$BINPATH}" + SERVERBIN="${RUN_ENGINE_SERVERBIN:-$SERVERBIN}" + CONFIG="${RUN_ENGINE_CONFIG:-$CONFIG}" + SESSION_MANAGER="${RUN_ENGINE_SESSION_MANAGER:-$SESSION_MANAGER}" + LOGS_PATH="${RUN_ENGINE_LOGS_PATH:-$LOGS_PATH}" + CRASHES_PATH="${RUN_ENGINE_CRASHES_PATH:-$CRASHES_PATH}" +} + +# Detect available session manager +function detect_session_manager() { + if command -v tmux >/dev/null 2>&1; then + echo "tmux" + elif command -v screen >/dev/null 2>&1; then + echo "screen" + else + echo "none" + fi +} + +# Determine which session manager to use +function get_session_manager() { + local requested="$1" + + case "$requested" in + "none") + echo "none" + ;; + "auto") + detect_session_manager + ;; + "tmux") + if command -v tmux >/dev/null 2>&1; then + echo "tmux" + else + echo "error" + fi + ;; + "screen") + if command -v screen >/dev/null 2>&1; then + echo "screen" + else + echo "error" + fi + ;; + *) + echo "none" + ;; + esac +} + +# Configure log files +function configure_files() { + TRACE_BEGIN_STRING="SIGSEGV" + TRACE_FILE="$LOGS_PATH/${LOG_PREFIX_NAME}_trace.log" + ERR_FILE="$LOGS_PATH/${LOG_PREFIX_NAME}_error.log" + SYSLOG="$LOGS_PATH/${LOG_PREFIX_NAME}_system.log" + SYSERR="$LOGS_PATH/${LOG_PREFIX_NAME}_system.err" + LINKS_FILE="$LOGS_PATH/${LOG_PREFIX_NAME}_crash_links.link" +} + +# Check if service is running +function check_status() { + local session_name="$1" + local ret=1 + + # Check for GDB process + local gdbres=$(pgrep -f "gdb.*--batch.*$SERVERBIN") + if [[ "$GDB_ENABLED" -eq 1 && -n "$gdbres" ]]; then + return 1 + fi + + # Check for binary process + local binres=$(pgrep -f "$SERVERBIN -c $CONFIG") + if [ -n "$binres" ]; then + return 1 + fi + + # Check session manager + if [ -n "$session_name" ]; then + case "$(get_session_manager "${SESSION_MANAGER:-auto}")" in + "tmux") + tmux has-session -t "$session_name" 2>/dev/null && return 1 + ;; + "screen") + screen -ls "$session_name" 2>/dev/null | grep -q "$session_name" && return 1 + ;; + esac + fi + + return 0 +} + +# Run with session manager +function run_with_session() { + local session_manager="$1" + local session_name="$2" + local wrapper="$3" + shift 3 + local args=("$@") + + if [ "$wrapper" = "simple-restarter" ]; then + script_path="$RUN_ENGINE_PATH/simple-restarter" + else + script_path="$RUN_ENGINE_PATH/starter" + fi + + case "$session_manager" in + "tmux") + echo "> Starting with tmux session: $session_name - attach with 'tmux attach -t $session_name'" + tmux new-session -d -s "$session_name" -- "$script_path" "${args[@]}" + ;; + "screen") + local OPTIONS="-A -m -d -S" + if [ -n "$SCREEN_OPTIONS" ]; then + OPTIONS="$SCREEN_OPTIONS" + fi + echo "> Starting with screen session: $session_name (options: $OPTIONS) - attach with 'screen -r $session_name'" + echo "screen $OPTIONS \"$session_name\" -- \"$script_path\" ${args[*]}" + screen $OPTIONS "$session_name" -- "$script_path" "${args[@]}" + ;; + "none"|*) + echo "> Starting without session manager" + "$script_path" "${args[@]}" + ;; + esac +} + +# Parse command line arguments +function parse_arguments() { + local mode="$1" + local serverbin="$2" + shift 2 + + local config_file="" + local serverconfig="" + local session_manager="" + + # Parse named arguments + while [[ $# -gt 0 ]]; do + case $1 in + --config) + config_file="$2" + shift 2 + ;; + --server-config) + serverconfig="$2" + shift 2 + ;; + --session-manager) + session_manager="$2" + shift 2 + ;; + *) + echo "Unknown argument: $1" + return 1 + ;; + esac + done + + # Export parsed values for use by start_service + export PARSED_MODE="$mode" + export PARSED_SERVERBIN="$serverbin" + export PARSED_CONFIG_FILE="$config_file" + export PARSED_SERVERCONFIG="$serverconfig" + export PARSED_SESSION_MANAGER="$session_manager" +} + +# Start service (single run or with simple-restarter) +function start_service() { + local config_file="$1" + local serverbin_path="$2" + local serverconfig="$3" + local use_restarter="${4:-false}" + local session_manager_choice="$5" + + # Load configuration first + load_config "$config_file" + + # if no session manager is specified, get it from config + if [ -z "$session_manager_choice" ]; then + session_manager_choice="$SESSION_MANAGER" + fi + + + # Parse serverbin_path to extract BINPATH and SERVERBIN + if [ -n "$serverbin_path" ]; then + # If it's a full path, extract directory and binary name + if [[ "$serverbin_path" == */* ]]; then + BINPATH="$(dirname "$serverbin_path")" + SERVERBIN="$(basename "$serverbin_path")" + else + # If it's just a binary name, use it as-is (system PATH) + SERVERBIN="$serverbin_path" + BINPATH="${BINPATH:-""}" # Empty means use current directory or system PATH + fi + fi + + # Use environment/config values if not set from command line + BINPATH="${BINPATH:-$RUN_ENGINE_BINPATH}" + SERVERBIN="${SERVERBIN:-$RUN_ENGINE_SERVERBIN}" + CONFIG="${serverconfig:-$RUN_ENGINE_CONFIG}" + + echo "SERVERBIN: $SERVERBIN" + + # Validate required parameters + if [ -z "$SERVERBIN" ]; then + echo "Error: SERVERBIN is required" + echo "Could not determine server binary from: $serverbin_path" + echo "Provide it as:" + echo " - Full path: $0 <mode> /path/to/bin/worldserver" + echo " - Binary name: $0 <mode> worldserver" + echo " - Environment variables: RUN_ENGINE_SERVERBIN" + echo " - Configuration file with SERVERBIN variable" + return 1 + fi + + # If BINPATH is set, validate binary exists and create log paths + if [ -n "$BINPATH" ]; then + if [ ! -d "$BINPATH" ]; then + echo "Error: BINPATH not found: $BINPATH" + return 1 + fi + + # Set up directories and logging relative to BINPATH + LOGS_PATH="${LOGS_PATH:-"$BINPATH/logs"}" + mkdir -p "$LOGS_PATH" + mkdir -p "$LOGS_PATH/crashes" + else + # For system binaries, try to detect binary location and create logs accordingly + local detected_binpath="" + + # Try to find binary in system PATH + local binary_location=$(which "$SERVERBIN" 2>/dev/null) + if [ -n "$binary_location" ]; then + detected_binpath="$(dirname "$binary_location")" + echo "Binary found in system PATH: $binary_location" + # Set BINPATH to the detected location so starter script can find the binary + BINPATH="$detected_binpath" + fi + + # Set up log paths based on detected or fallback location + if [ -n "$detected_binpath" ]; then + LOGS_PATH="${LOGS_PATH:-"$detected_binpath/logs"}" + else + # Fallback to current directory for logs + LOGS_PATH="${LOGS_PATH:-./logs}" + fi + + CRASHES_PATH="${CRASHES_PATH:-"$LOGS_PATH/crashes"}" + + mkdir -p "$LOGS_PATH" + mkdir -p "$CRASHES_PATH" + fi + + # Set up logging names + LOG_PREFIX_NAME="${LOG_PREFIX_NAME:-${SERVERBIN%server}}" + + # Set up session name (with backward compatibility for SCREEN_NAME) + SESSION_NAME="${SESSION_NAME:-$SCREEN_NAME}" + SESSION_NAME="${SESSION_NAME:-AC-${SERVERBIN%server}}" + + configure_files + + local session_manager=$(get_session_manager "$session_manager_choice") + + if [ "$session_manager" = "error" ]; then + echo "Error: Invalid session manager specified: $session_manager_choice, is it installed?" + exit 1 + fi + + echo "Using session manager: $session_manager" + echo "Starting server: $SERVERBIN" + + if [ -n "$CONFIG" ]; then + echo "Server config: $CONFIG" + else + echo "Server config: default (not specified)" + fi + + if [ "$use_restarter" = "true" ]; then + # Use simple-restarter for restart functionality + local gdb_enabled="${GDB_ENABLED:-0}" + run_with_session "$session_manager" "$SESSION_NAME" "simple-restarter" "$BINPATH" "$SERVERBIN" "$GDB" "$CONFIG" "$SYSLOG" "$SYSERR" "$gdb_enabled" "$CRASHES_PATH" + else + # Single run using starter + local gdb_enabled="${GDB_ENABLED:-0}" + run_with_session "$session_manager" "$SESSION_NAME" "starter" "$BINPATH" "$SERVERBIN" "$GDB" "$CONFIG" "$SYSLOG" "$SYSERR" "$gdb_enabled" "$CRASHES_PATH" + fi +} + +# Cleanup function +function finish() { + local session_manager=$(get_session_manager "${SESSION_MANAGER:-auto}") + if [ -n "$SESSION_NAME" ]; then + case "$session_manager" in + "tmux") + tmux kill-session -t "$SESSION_NAME" 2>/dev/null || true + ;; + "screen") + screen -X -S "$SESSION_NAME" quit 2>/dev/null || true + ;; + esac + fi +} + +# Legacy compatibility functions for old examples +function restarter() { + echo "Legacy function 'restarter' called - redirecting to new API" + start_service "" "" "" "true" "${SESSION_MANAGER:-auto}" +} + +function starter() { + echo "Legacy function 'starter' called - redirecting to new API" + start_service "" "" "" "false" "${SESSION_MANAGER:-auto}" +} + +# Set trap for cleanup (currently disabled to avoid interfering with systemd) +# trap finish EXIT + +# Main execution when script is run directly +if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then + case "${1:-help}" in + "start"|"restart") + if [ $# -lt 2 ]; then + echo "Error: Missing required arguments" + echo "Usage: $0 <mode> <serverbin> [options]" + echo "Example: $0 start worldserver --config ./conf-world.sh --server-config worldserver.conf" + exit 1 + fi + + # Parse arguments + if ! parse_arguments "$@"; then + exit 1 + fi + + # Determine restart mode + use_restarter="false" + if [ "$PARSED_MODE" = "restart" ]; then + use_restarter="true" + fi + + # Start service with parsed arguments + start_service "$PARSED_CONFIG_FILE" "$PARSED_SERVERBIN" "$PARSED_SERVERCONFIG" "$use_restarter" "$PARSED_SESSION_MANAGER" + ;; + "help"|*) + echo "AzerothCore Run Engine" + echo "" + echo "Usage: $0 <mode> <serverbin> [options]" + echo "" + echo "Modes:" + echo " start - Start service once (no restart on crash)" + echo " restart - Start service with restart on crash (uses simple-restarter)" + echo "" + echo "Required Parameters:" + echo " serverbin - Server binary (full path or binary name)" + echo " Full path: /path/to/bin/worldserver" + echo " Binary name: worldserver (uses system PATH)" + echo "" + echo "Options:" + echo " --config <file> - Path to configuration file" + echo " --server-config <file> - Server configuration file (sets -c parameter)" + echo " --session-manager <type> - Session manager: none|auto|tmux|screen (default: auto)" + echo "" + echo "Configuration Priority (highest to lowest):" + echo " 1. conf.sh - User configuration file" + echo " 2. Command line arguments (--config, --server-config, etc.)" + echo " 3. Environment variables (RUN_ENGINE_*)" + echo " 4. conf.sh.dist - Default configuration" + echo "" + echo "Environment Variables:" + echo " RUN_ENGINE_CONFIG_FILE - Config file path" + echo " RUN_ENGINE_SESSION_MANAGER - Session manager (default: auto)" + echo " RUN_ENGINE_BINPATH - Binary directory path" + echo " RUN_ENGINE_SERVERBIN - Server binary name" + echo " RUN_ENGINE_CONFIG - Server configuration file" + echo " RUN_ENGINE_LOGS_PATH - Directory for log files" + echo " RUN_ENGINE_CRASHES_PATH - Directory for crash dumps" + echo " RUN_ENGINE_SESSION_NAME - Session name for tmux/screen" + echo "" + echo "Examples:" + echo "" + echo " # Using full path to binary" + echo " $0 start /home/user/ac/bin/worldserver" + echo "" + echo " # Using binary name (system PATH)" + echo " $0 start worldserver" + echo "" + echo " # With configuration file" + echo " $0 start worldserver --config ./conf-world.sh" + echo "" + echo " # With server configuration (sets -c parameter)" + echo " $0 start /path/to/bin/worldserver --server-config /etc/worldserver.conf" + echo "" + echo " # With session manager" + echo " $0 restart worldserver --session-manager tmux" + echo "" + echo " # Complete example" + echo " $0 restart /home/user/ac/bin/worldserver --config ./conf-world.sh --server-config worldserver.conf --session-manager screen" + echo "" + echo "Binary Resolution:" + echo " - Full path (contains /): Extracts directory and binary name" + echo " - Binary name only: Uses system PATH to find executable" + echo " Auto-detection will check current directory first, then system PATH" + echo "" + echo "Server Config:" + echo " If --server-config is specified, it's passed as -c parameter to the server." + echo " If not specified, the server will use its default configuration." + ;; + esac +fi + |