mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-13 01:08:35 +00:00
@@ -100,7 +100,8 @@ git clone --depth=1 --branch=main https://github.com/azerothcore/mod-system-vi
|
||||
git clone --depth=1 --branch=master https://github.com/azerothcore/mod-tic-tac-toe modules/mod-tic-tac-toe
|
||||
git clone --depth=1 --branch=master https://github.com/azerothcore/mod-top-arena modules/mod-top-arena
|
||||
git clone --depth=1 --branch=master https://github.com/azerothcore/mod-transmog modules/mod-transmog
|
||||
git clone --depth=1 --branch=master https://github.com/azerothcore/mod-war-effort modules/mod-war-effort
|
||||
# archived / outdated
|
||||
#git clone --depth=1 --branch=master https://github.com/azerothcore/mod-war-effort modules/mod-war-effort
|
||||
git clone --depth=1 --branch=master https://github.com/azerothcore/mod-weekend-xp modules/mod-weekend-xp
|
||||
git clone --depth=1 --branch=master https://github.com/azerothcore/mod-who-logged modules/mod-who-logged
|
||||
git clone --depth=1 --branch=master https://github.com/azerothcore/mod-zone-difficulty modules/mod-zone-difficulty
|
||||
|
||||
@@ -312,6 +312,9 @@ Services support two restart policies:
|
||||
|
||||
# Edit configuration
|
||||
./service-manager.sh edit world
|
||||
|
||||
# Restore missing services from registry
|
||||
./service-manager.sh restore
|
||||
```
|
||||
|
||||
## 🌍 Multiple Realms Setup
|
||||
@@ -384,22 +387,72 @@ cp examples/restarter-world.sh restarter-realm2.sh
|
||||
|
||||
## 🛠️ Service Management
|
||||
|
||||
### Service Registry and Persistence
|
||||
|
||||
The service manager includes a comprehensive registry system that tracks all created services and enables automatic restoration:
|
||||
|
||||
#### Service Registry Features
|
||||
|
||||
- **Automatic Tracking**: All services are automatically registered when created
|
||||
- **Cross-Reboot Persistence**: PM2 services are configured with startup persistence
|
||||
- **Service Restoration**: Missing services can be detected and restored from registry
|
||||
- **Migration Support**: Legacy service configurations can be migrated to the new format
|
||||
|
||||
#### Using the Registry
|
||||
|
||||
```bash
|
||||
# Check for missing services and restore them
|
||||
./service-manager.sh restore
|
||||
|
||||
# List all registered services (includes status)
|
||||
./service-manager.sh list
|
||||
|
||||
# Services are automatically added to registry on creation
|
||||
./service-manager.sh create auth authserver --bin-path /path/to/bin
|
||||
```
|
||||
|
||||
#### Custom Configuration Directories
|
||||
|
||||
You can customize where service configurations and PM2/systemd files are stored:
|
||||
|
||||
```bash
|
||||
# Set custom directories
|
||||
export AC_SERVICE_CONFIG_DIR="/path/to/your/project/services"
|
||||
|
||||
# Now all service operations will use these custom directories
|
||||
./service-manager.sh create auth authserver --bin-path /path/to/bin
|
||||
```
|
||||
|
||||
This is particularly useful for:
|
||||
- **Version Control**: Keep service configurations in your project repository
|
||||
- **Multiple Projects**: Separate service configurations per project
|
||||
- **Team Collaboration**: Share service setups across development teams
|
||||
|
||||
#### Migration from Legacy Format
|
||||
|
||||
If you have existing services in the old format, use the migration script:
|
||||
|
||||
```bash
|
||||
# Migrate existing registry to new format
|
||||
./migrate-registry.sh
|
||||
|
||||
# The script will:
|
||||
# - Detect old format automatically
|
||||
# - Create a backup of the old registry
|
||||
# - Convert to new format with proper tracking
|
||||
# - Preserve all existing service information
|
||||
```
|
||||
|
||||
### PM2 Services
|
||||
|
||||
When using PM2 as the service provider:
|
||||
|
||||
```bash
|
||||
# PM2-specific commands
|
||||
pm2 list # List all PM2 processes
|
||||
pm2 logs auth # View logs
|
||||
pm2 monit # Real-time monitoring
|
||||
pm2 restart auth # Restart service
|
||||
pm2 delete auth # Remove service
|
||||
* [PM2 CLI Documentation](https://pm2.io/docs/runtime/reference/pm2-cli/)
|
||||
|
||||
# Save PM2 configuration
|
||||
pm2 save
|
||||
pm2 startup # Auto-start on boot
|
||||
```
|
||||
**Automatic PM2 Persistence**: The service manager automatically configures PM2 for persistence across reboots by:
|
||||
- Running `pm2 startup` to set up the startup script
|
||||
- Running `pm2 save` after each service creation/modification
|
||||
- This ensures your services automatically start when the system reboots
|
||||
|
||||
NOTE: pm2 cannot run tmux/screen sessions, but you can always use the `attach` command to connect to the service console because pm2 supports interactive mode.
|
||||
|
||||
@@ -407,6 +460,12 @@ NOTE: pm2 cannot run tmux/screen sessions, but you can always use the `attach` c
|
||||
|
||||
The startup scripts recognize several environment variables for configuration and runtime behavior:
|
||||
|
||||
#### Configuration Directory Variables
|
||||
|
||||
- **`AC_SERVICE_CONFIG_DIR`**: Override the default configuration directory for services registry and configurations
|
||||
- Default: `${XDG_CONFIG_HOME:-$HOME/.config}/azerothcore/services`
|
||||
- Used for storing service registry and run-engine configurations
|
||||
|
||||
#### Service Detection Variables
|
||||
|
||||
- **`AC_LAUNCHED_BY_PM2`**: Set to `1` when launched by PM2 (automatically set by service-manager)
|
||||
@@ -551,4 +610,18 @@ npm install -g pm2
|
||||
sudo npm install -g pm2
|
||||
```
|
||||
|
||||
#### 7. Registry Out of Sync
|
||||
```bash
|
||||
# If the service registry shows services that don't actually exist
|
||||
```
|
||||
**Solution**: Use registry sync or restore
|
||||
```bash
|
||||
# Check and restore missing services (also cleans up orphaned entries)
|
||||
./service-manager.sh restore
|
||||
|
||||
# If you have a very old registry format, migrate it
|
||||
./migrate-registry.sh
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
144
apps/startup-scripts/src/migrate-registry.sh
Executable file
144
apps/startup-scripts/src/migrate-registry.sh
Executable file
@@ -0,0 +1,144 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# One-time migration script for service registry
|
||||
# Converts old format to new format
|
||||
|
||||
set -euo pipefail # Strict error handling
|
||||
|
||||
CONFIG_DIR="${AC_SERVICE_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/azerothcore/services}"
|
||||
REGISTRY_FILE="$CONFIG_DIR/service_registry.json"
|
||||
BACKUP_FILE="$CONFIG_DIR/service_registry.json.backup"
|
||||
|
||||
# Colors
|
||||
readonly YELLOW='\033[1;33m'
|
||||
readonly GREEN='\033[0;32m'
|
||||
readonly RED='\033[0;31m'
|
||||
readonly BLUE='\033[0;34m'
|
||||
readonly NC='\033[0m'
|
||||
|
||||
echo -e "${BLUE}AzerothCore Service Registry Migration Tool${NC}"
|
||||
echo "=============================================="
|
||||
|
||||
# Check dependencies
|
||||
if ! command -v jq >/dev/null 2>&1; then
|
||||
echo -e "${RED}Error: jq is required but not installed. Please install jq package.${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Create config directory if it doesn't exist
|
||||
mkdir -p "$CONFIG_DIR"
|
||||
|
||||
# Check if registry exists
|
||||
if [ ! -f "$REGISTRY_FILE" ]; then
|
||||
echo -e "${YELLOW}No registry file found. Nothing to migrate.${NC}"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Validate JSON format
|
||||
if ! jq empty "$REGISTRY_FILE" >/dev/null 2>&1; then
|
||||
echo -e "${RED}Error: Registry file contains invalid JSON.${NC}"
|
||||
echo "Please check the file: $REGISTRY_FILE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if it's already new format
|
||||
if jq -e 'type == "array" and (length == 0 or .[0] | has("bin_path"))' "$REGISTRY_FILE" >/dev/null 2>&1; then
|
||||
echo -e "${GREEN}Registry is already in new format. No migration needed.${NC}"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Check if it's old format
|
||||
if ! jq -e 'type == "array" and (length == 0 or .[0] | has("config"))' "$REGISTRY_FILE" >/dev/null 2>&1; then
|
||||
echo -e "${YELLOW}Registry format not recognized. Manual review needed.${NC}"
|
||||
echo "Current registry content:"
|
||||
cat "$REGISTRY_FILE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -e "${YELLOW}Old format detected. Starting migration...${NC}"
|
||||
|
||||
# Create backup
|
||||
if ! cp "$REGISTRY_FILE" "$BACKUP_FILE"; then
|
||||
echo -e "${RED}Error: Failed to create backup file.${NC}"
|
||||
exit 1
|
||||
fi
|
||||
echo -e "${BLUE}Backup created: $BACKUP_FILE${NC}"
|
||||
|
||||
# Convert to new format
|
||||
echo "[]" > "$REGISTRY_FILE.new"
|
||||
|
||||
services_migrated=0
|
||||
while IFS= read -r service; do
|
||||
if [ -n "$service" ] && [ "$service" != "null" ]; then
|
||||
name=$(echo "$service" | jq -r '.name // ""')
|
||||
provider=$(echo "$service" | jq -r '.provider // ""')
|
||||
type=$(echo "$service" | jq -r '.type // ""')
|
||||
config=$(echo "$service" | jq -r '.config // ""')
|
||||
|
||||
# Validate required fields
|
||||
if [ -z "$name" ] || [ -z "$provider" ] || [ -z "$type" ]; then
|
||||
echo -e "${YELLOW}Skipping invalid service entry: $service${NC}"
|
||||
continue
|
||||
fi
|
||||
|
||||
echo -e "${YELLOW}Migrating service: $name${NC}"
|
||||
|
||||
# Create new format entry with all required fields
|
||||
new_entry=$(jq -n \
|
||||
--arg name "$name" \
|
||||
--arg provider "$provider" \
|
||||
--arg type "$type" \
|
||||
--arg bin_path "unknown" \
|
||||
--arg args "" \
|
||||
--arg created "$(date -Iseconds)" \
|
||||
--arg status "migrated" \
|
||||
--arg systemd_type "--user" \
|
||||
--arg restart_policy "always" \
|
||||
--arg session_manager "none" \
|
||||
--arg gdb_enabled "0" \
|
||||
--arg pm2_opts "" \
|
||||
--arg server_config "" \
|
||||
--arg legacy_config "$config" \
|
||||
'{
|
||||
name: $name,
|
||||
provider: $provider,
|
||||
type: $type,
|
||||
bin_path: $bin_path,
|
||||
args: $args,
|
||||
created: $created,
|
||||
status: $status,
|
||||
systemd_type: $systemd_type,
|
||||
restart_policy: $restart_policy,
|
||||
session_manager: $session_manager,
|
||||
gdb_enabled: $gdb_enabled,
|
||||
pm2_opts: $pm2_opts,
|
||||
server_config: $server_config,
|
||||
legacy_config: $legacy_config
|
||||
}')
|
||||
|
||||
# Add to new registry with error checking
|
||||
if ! jq --argjson entry "$new_entry" '. += [$entry]' "$REGISTRY_FILE.new" > "$REGISTRY_FILE.new.tmp"; then
|
||||
echo -e "${RED}Error: Failed to add service $name to new registry${NC}"
|
||||
rm -f "$REGISTRY_FILE.new" "$REGISTRY_FILE.new.tmp"
|
||||
exit 1
|
||||
fi
|
||||
mv "$REGISTRY_FILE.new.tmp" "$REGISTRY_FILE.new"
|
||||
|
||||
services_migrated=$((services_migrated + 1))
|
||||
fi
|
||||
done < <(jq -c '.[]?' "$BACKUP_FILE" 2>/dev/null || echo "")
|
||||
|
||||
# Replace old registry with new one
|
||||
if ! mv "$REGISTRY_FILE.new" "$REGISTRY_FILE"; then
|
||||
echo -e "${RED}Error: Failed to replace old registry with new one${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -e "${GREEN}Migration completed successfully!${NC}"
|
||||
echo -e "${BLUE}Services migrated: $services_migrated${NC}"
|
||||
echo -e "${BLUE}Use 'service-manager.sh restore' to review and update services.${NC}"
|
||||
echo -e "${YELLOW}Note: Migrated services have bin_path='unknown' and need manual recreation.${NC}"
|
||||
echo ""
|
||||
echo -e "${BLUE}To recreate services, use commands like:${NC}"
|
||||
echo " ./service-manager.sh create auth authserver --provider pm2 --bin-path /path/to/your/bin"
|
||||
echo " ./service-manager.sh create world worldserver --provider systemd --bin-path /path/to/your/bin"
|
||||
@@ -4,6 +4,8 @@
|
||||
# A unified interface for managing AzerothCore services with PM2 or systemd
|
||||
# This script provides commands to create, update, delete, and manage server instances
|
||||
|
||||
set -euo pipefail # Strict error handling
|
||||
|
||||
# Script location
|
||||
CURRENT_PATH="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
@@ -11,16 +13,16 @@ SCRIPT_DIR="$CURRENT_PATH"
|
||||
|
||||
ROOT_DIR="$(cd "$CURRENT_PATH/../../.." && pwd)"
|
||||
|
||||
# Configuration directory
|
||||
CONFIG_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/azerothcore/services"
|
||||
# Configuration directory (can be overridden with AC_SERVICE_CONFIG_DIR)
|
||||
CONFIG_DIR="${AC_SERVICE_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/azerothcore/services}"
|
||||
REGISTRY_FILE="$CONFIG_DIR/service_registry.json"
|
||||
|
||||
# Colors for output
|
||||
YELLOW='\033[1;33m'
|
||||
GREEN='\033[0;32m'
|
||||
RED='\033[0;31m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
readonly YELLOW='\033[1;33m'
|
||||
readonly GREEN='\033[0;32m'
|
||||
readonly RED='\033[0;31m'
|
||||
readonly BLUE='\033[0;34m'
|
||||
readonly NC='\033[0m' # No Color
|
||||
|
||||
# Create config directory if it doesn't exist
|
||||
mkdir -p "$CONFIG_DIR"
|
||||
@@ -38,6 +40,198 @@ check_dependencies() {
|
||||
}
|
||||
}
|
||||
|
||||
# Registry management functions
|
||||
function add_service_to_registry() {
|
||||
local service_name="$1"
|
||||
local provider="$2"
|
||||
local service_type="$3"
|
||||
local bin_path="$4"
|
||||
local args="$5"
|
||||
local systemd_type="$6"
|
||||
local restart_policy="$7"
|
||||
local session_manager="$8"
|
||||
local gdb_enabled="$9"
|
||||
local pm2_opts="${10}"
|
||||
local server_config="${11}"
|
||||
|
||||
# Remove any existing entry with the same service name to avoid duplicates
|
||||
local tmp_file
|
||||
tmp_file=$(mktemp)
|
||||
jq --arg name "$service_name" 'map(select(.name != $name))' "$REGISTRY_FILE" > "$tmp_file" && mv "$tmp_file" "$REGISTRY_FILE"
|
||||
|
||||
# Add the new entry to the registry
|
||||
tmp_file=$(mktemp)
|
||||
jq --arg name "$service_name" \
|
||||
--arg provider "$provider" \
|
||||
--arg type "$service_type" \
|
||||
--arg bin_path "$bin_path" \
|
||||
--arg args "$args" \
|
||||
--arg created "$(date -Iseconds)" \
|
||||
--arg systemd_type "$systemd_type" \
|
||||
--arg restart_policy "$restart_policy" \
|
||||
--arg session_manager "$session_manager" \
|
||||
--arg gdb_enabled "$gdb_enabled" \
|
||||
--arg pm2_opts "$pm2_opts" \
|
||||
--arg server_config "$server_config" \
|
||||
'. += [{"name": $name, "provider": $provider, "type": $type, "bin_path": $bin_path, "args": $args, "created": $created, "status": "active", "systemd_type": $systemd_type, "restart_policy": $restart_policy, "session_manager": $session_manager, "gdb_enabled": $gdb_enabled, "pm2_opts": $pm2_opts, "server_config": $server_config}]' \
|
||||
"$REGISTRY_FILE" > "$tmp_file" && mv "$tmp_file" "$REGISTRY_FILE"
|
||||
|
||||
echo -e "${GREEN}Service '$service_name' added to registry${NC}"
|
||||
}
|
||||
|
||||
function remove_service_from_registry() {
|
||||
local service_name="$1"
|
||||
|
||||
if [ -f "$REGISTRY_FILE" ]; then
|
||||
local tmp_file
|
||||
tmp_file=$(mktemp)
|
||||
jq --arg name "$service_name" \
|
||||
'map(select(.name != $name))' \
|
||||
"$REGISTRY_FILE" > "$tmp_file" && mv "$tmp_file" "$REGISTRY_FILE"
|
||||
echo -e "${GREEN}Service '$service_name' removed from registry${NC}"
|
||||
fi
|
||||
}
|
||||
|
||||
function restore_missing_services() {
|
||||
echo -e "${BLUE}Checking for missing services...${NC}"
|
||||
|
||||
if [ ! -f "$REGISTRY_FILE" ] || [ ! -s "$REGISTRY_FILE" ]; then
|
||||
echo -e "${YELLOW}No services registry found or empty${NC}"
|
||||
return 0
|
||||
fi
|
||||
|
||||
local missing_services=()
|
||||
local services_count
|
||||
services_count=$(jq length "$REGISTRY_FILE")
|
||||
|
||||
if [ "$services_count" -eq 0 ]; then
|
||||
echo -e "${YELLOW}No services registered${NC}"
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo -e "${BLUE}Found $services_count registered services. Checking status...${NC}"
|
||||
|
||||
# Check each service
|
||||
for i in $(seq 0 $((services_count-1))); do
|
||||
local service=$(jq -r ".[$i]" "$REGISTRY_FILE")
|
||||
local name=$(echo "$service" | jq -r '.name')
|
||||
local provider=$(echo "$service" | jq -r '.provider')
|
||||
local service_type=$(echo "$service" | jq -r '.type')
|
||||
local bin_path=$(echo "$service" | jq -r '.bin_path // "unknown"')
|
||||
local args=$(echo "$service" | jq -r '.args // ""')
|
||||
local status=$(echo "$service" | jq -r '.status // "active"')
|
||||
local systemd_type=$(echo "$service" | jq -r '.systemd_type // "--user"')
|
||||
local restart_policy=$(echo "$service" | jq -r '.restart_policy // "always"')
|
||||
local session_manager=$(echo "$service" | jq -r '.session_manager // "none"')
|
||||
local gdb_enabled=$(echo "$service" | jq -r '.gdb_enabled // "0"')
|
||||
local pm2_opts=$(echo "$service" | jq -r '.pm2_opts // ""')
|
||||
local server_config=$(echo "$service" | jq -r '.server_config // ""')
|
||||
|
||||
local service_exists=false
|
||||
|
||||
if [ "$provider" = "pm2" ]; then
|
||||
if pm2 describe "$name" >/dev/null 2>&1; then
|
||||
service_exists=true
|
||||
fi
|
||||
elif [ "$provider" = "systemd" ]; then
|
||||
local user_unit="${XDG_CONFIG_HOME:-$HOME/.config}/systemd/user/$name.service"
|
||||
local system_unit="/etc/systemd/system/$name.service"
|
||||
if [ -f "$user_unit" ] || [ -f "$system_unit" ]; then
|
||||
# Unit file present, you can also check if it is active
|
||||
service_exists=true
|
||||
else
|
||||
# Unit file missing: service needs to be recreated!
|
||||
service_exists=false
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$service_exists" = false ]; then
|
||||
missing_services+=("$i")
|
||||
echo -e "${YELLOW}Missing service: $name ($provider)${NC}"
|
||||
else
|
||||
echo -e "${GREEN}✓ Service $name ($provider) exists${NC}"
|
||||
fi
|
||||
done
|
||||
|
||||
# Handle missing services
|
||||
if [ ${#missing_services[@]} -eq 0 ]; then
|
||||
echo -e "${GREEN}All registered services are present${NC}"
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo -e "${YELLOW}Found ${#missing_services[@]} missing services${NC}"
|
||||
|
||||
for index in "${missing_services[@]}"; do
|
||||
local service=$(jq -r ".[$index]" "$REGISTRY_FILE")
|
||||
local name=$(echo "$service" | jq -r '.name')
|
||||
local provider=$(echo "$service" | jq -r '.provider')
|
||||
local service_type=$(echo "$service" | jq -r '.type')
|
||||
local bin_path=$(echo "$service" | jq -r '.bin_path')
|
||||
local args=$(echo "$service" | jq -r '.args')
|
||||
local systemd_type=$(echo "$service" | jq -r '.systemd_type // "--user"')
|
||||
local restart_policy=$(echo "$service" | jq -r '.restart_policy // "always"')
|
||||
local session_manager=$(echo "$service" | jq -r '.session_manager // "none"')
|
||||
local gdb_enabled=$(echo "$service" | jq -r '.gdb_enabled // "0"')
|
||||
local pm2_opts=$(echo "$service" | jq -r '.pm2_opts // ""')
|
||||
local server_config=$(echo "$service" | jq -r '.server_config // ""')
|
||||
|
||||
echo ""
|
||||
echo -e "${YELLOW}Service '$name' ($provider) is missing${NC}"
|
||||
echo " Type: $service_type"
|
||||
echo " Status: $status"
|
||||
|
||||
if [ "$bin_path" = "unknown" ] || [ "$bin_path" = "null" ] || [ "$status" = "migrated" ]; then
|
||||
echo " Binary: <needs manual configuration>"
|
||||
echo " Args: <needs manual configuration>"
|
||||
echo ""
|
||||
echo -e "${YELLOW}This service needs to be recreated manually:${NC}"
|
||||
echo " $0 create $service_type $name --provider $provider --bin-path /path/to/your/bin"
|
||||
else
|
||||
echo " Binary: $bin_path"
|
||||
echo " Args: $args"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
read -p "Do you want to (r)ecreate, (d)elete from registry, or (s)kip? [r/d/s]: " choice
|
||||
|
||||
case "$choice" in
|
||||
r|R|recreate)
|
||||
if [ "$bin_path" = "unknown" ] || [ "$status" = "migrated" ]; then
|
||||
echo -e "${YELLOW}Please recreate manually with full create command${NC}"
|
||||
read -p "Remove this entry from registry? [y/n]: " remove_entry
|
||||
if [[ "$remove_entry" =~ ^[Yy]$ ]]; then
|
||||
remove_service_from_registry "$name"
|
||||
fi
|
||||
else
|
||||
echo -e "${BLUE}Recreating service '$name'...${NC}"
|
||||
if [ "$provider" = "pm2" ]; then
|
||||
if [ "$args" != "null" ] && [ -n "$args" ]; then
|
||||
pm2_create_service "$name" "$bin_path $args" "$restart_policy" $pm2_opts
|
||||
else
|
||||
pm2_create_service "$name" "$bin_path" "$restart_policy" $pm2_opts
|
||||
fi
|
||||
elif [ "$provider" = "systemd" ]; then
|
||||
echo -e "${BLUE}Attempting to recreate systemd service '$name' automatically...${NC}"
|
||||
if systemd_create_service "$name" "$bin_path $args" "$restart_policy" "$systemd_type" "$session_manager" "$gdb_enabled" "$server_config"; then
|
||||
echo -e "${GREEN}Systemd service '$name' recreated successfully${NC}"
|
||||
else
|
||||
echo -e "${RED}Failed to recreate systemd service '$name'. Please recreate manually.${NC}"
|
||||
echo " $0 create $name $service_type --provider systemd --bin-path $bin_path"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
d|D|delete)
|
||||
echo -e "${BLUE}Removing '$name' from registry...${NC}"
|
||||
remove_service_from_registry "$name"
|
||||
;;
|
||||
s|S|skip|*)
|
||||
echo -e "${BLUE}Skipping '$name'${NC}"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
# Check if PM2 is installed
|
||||
check_pm2() {
|
||||
if ! command -v pm2 >/dev/null 2>&1; then
|
||||
@@ -81,6 +275,7 @@ function print_help() {
|
||||
echo " $base_name update <service-name> [options]"
|
||||
echo " $base_name delete <service-name>"
|
||||
echo " $base_name list [provider]"
|
||||
echo " $base_name restore"
|
||||
echo " $base_name start|stop|restart|status <service-name>"
|
||||
echo " $base_name logs <service-name> [--follow]"
|
||||
echo " $base_name attach <service-name>"
|
||||
@@ -139,6 +334,9 @@ function print_help() {
|
||||
echo " $base_name attach worldserver-realm1"
|
||||
echo " $base_name list pm2"
|
||||
echo ""
|
||||
echo " # Restore missing services from registry"
|
||||
echo " $base_name restore"
|
||||
echo ""
|
||||
echo "Notes:"
|
||||
echo " - Configuration editing modifies run-engine settings (GDB, session manager, etc.)"
|
||||
echo " - Use --server-config for the actual server configuration file"
|
||||
@@ -150,26 +348,13 @@ function print_help() {
|
||||
echo " - attach command automatically detects the configured session manager and connects appropriately"
|
||||
echo " - attach always provides interactive access to the server console"
|
||||
echo " - Use 'logs' command to view service logs without interaction"
|
||||
echo " - restore command checks registry and helps recreate missing services"
|
||||
echo ""
|
||||
echo "Environment Variables:"
|
||||
echo " AC_SERVICE_CONFIG_DIR - Override default config directory for services registry"
|
||||
}
|
||||
|
||||
function register_service() {
|
||||
local service_name="$1"
|
||||
local provider="$2"
|
||||
local service_type="$3"
|
||||
local config_file="$CONFIG_DIR/$service_name.conf"
|
||||
|
||||
# Add to registry
|
||||
local tmp_file=$(mktemp)
|
||||
jq --arg name "$service_name" \
|
||||
--arg provider "$provider" \
|
||||
--arg type "$service_type" \
|
||||
--arg config "$config_file" \
|
||||
'. += [{"name": $name, "provider": $provider, "type": $type, "config": $config}]' \
|
||||
"$REGISTRY_FILE" > "$tmp_file"
|
||||
mv "$tmp_file" "$REGISTRY_FILE"
|
||||
|
||||
echo -e "${GREEN}Service $service_name registered successfully${NC}"
|
||||
}
|
||||
|
||||
|
||||
function validate_service_exists() {
|
||||
local service_name="$1"
|
||||
@@ -210,47 +395,42 @@ function validate_service_exists() {
|
||||
function sync_registry() {
|
||||
echo -e "${YELLOW}Syncing service registry with actual services...${NC}"
|
||||
|
||||
local services=$(jq -c '.[]' "$REGISTRY_FILE")
|
||||
local tmp_file=$(mktemp)
|
||||
if [ ! -f "$REGISTRY_FILE" ] || [ ! -s "$REGISTRY_FILE" ]; then
|
||||
echo -e "${YELLOW}No services registry found or empty${NC}"
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Initialize with empty array
|
||||
local services_count=$(jq length "$REGISTRY_FILE")
|
||||
if [ "$services_count" -eq 0 ]; then
|
||||
echo -e "${YELLOW}No services registered${NC}"
|
||||
return 0
|
||||
fi
|
||||
|
||||
local tmp_file=$(mktemp)
|
||||
echo "[]" > "$tmp_file"
|
||||
|
||||
# Check each service in registry
|
||||
while read -r service_info; do
|
||||
if [ -n "$service_info" ]; then
|
||||
local name=$(echo "$service_info" | jq -r '.name')
|
||||
local provider=$(echo "$service_info" | jq -r '.provider')
|
||||
|
||||
if validate_service_exists "$name" "$provider"; then
|
||||
# Service exists, add it to the new registry
|
||||
jq --argjson service "$service_info" '. += [$service]' "$tmp_file" > "$tmp_file.new"
|
||||
mv "$tmp_file.new" "$tmp_file"
|
||||
else
|
||||
echo -e "${YELLOW}Service '$name' no longer exists. Removing from registry.${NC}"
|
||||
# Don't add to new registry
|
||||
fi
|
||||
for i in $(seq 0 $((services_count-1))); do
|
||||
local service=$(jq -r ".[$i]" "$REGISTRY_FILE")
|
||||
local name=$(echo "$service" | jq -r '.name')
|
||||
local provider=$(echo "$service" | jq -r '.provider')
|
||||
|
||||
if validate_service_exists "$name" "$provider"; then
|
||||
# Service exists, add it to the new registry
|
||||
jq --argjson service "$service" '. += [$service]' "$tmp_file" > "$tmp_file.new"
|
||||
mv "$tmp_file.new" "$tmp_file"
|
||||
else
|
||||
echo -e "${YELLOW}Service '$name' no longer exists. Removing from registry.${NC}"
|
||||
# Don't add to new registry
|
||||
fi
|
||||
done <<< "$services"
|
||||
done
|
||||
|
||||
# Replace registry with synced version
|
||||
mv "$tmp_file" "$REGISTRY_FILE"
|
||||
echo -e "${GREEN}Registry synchronized.${NC}"
|
||||
}
|
||||
|
||||
function unregister_service() {
|
||||
local service_name="$1"
|
||||
|
||||
# Remove from registry
|
||||
local tmp_file=$(mktemp)
|
||||
jq --arg name "$service_name" '. | map(select(.name != $name))' "$REGISTRY_FILE" > "$tmp_file"
|
||||
mv "$tmp_file" "$REGISTRY_FILE"
|
||||
|
||||
# Remove configuration file
|
||||
rm -f "$CONFIG_DIR/$service_name.conf"
|
||||
|
||||
echo -e "${GREEN}Service $service_name unregistered${NC}"
|
||||
}
|
||||
|
||||
|
||||
function get_service_info() {
|
||||
local service_name="$1"
|
||||
@@ -317,6 +497,15 @@ function pm2_create_service() {
|
||||
if eval "$pm2_cmd"; then
|
||||
echo -e "${GREEN}PM2 service '$service_name' created successfully${NC}"
|
||||
pm2 save
|
||||
|
||||
# Setup PM2 startup for persistence across reboots
|
||||
echo -e "${BLUE}Configuring PM2 startup for persistence...${NC}"
|
||||
pm2 startup --auto >/dev/null 2>&1 || true
|
||||
|
||||
# Add to registry (extract command and args from the full command)
|
||||
local clean_command="$command$additional_args"
|
||||
add_service_to_registry "$service_name" "pm2" "executable" "$command" "$additional_args" "" "$restart_policy" "none" "0" "$max_memory $max_restarts" ""
|
||||
|
||||
return 0
|
||||
else
|
||||
echo -e "${RED}Failed to create PM2 service '$service_name'${NC}"
|
||||
@@ -334,8 +523,8 @@ function pm2_remove_service() {
|
||||
|
||||
# Stop the service if it's running
|
||||
if pm2 describe "$service_name" >/dev/null 2>&1; then
|
||||
pm2 stop "$service_name" 2>/dev/null || true
|
||||
pm2 delete "$service_name" 2>/dev/null
|
||||
pm2 stop "$service_name" 2>&1 || true
|
||||
pm2 delete "$service_name" 2>&1 || true
|
||||
|
||||
# Wait for PM2 to process the stop/delete command with timeout
|
||||
local timeout=10
|
||||
@@ -357,8 +546,13 @@ function pm2_remove_service() {
|
||||
|
||||
pm2 save
|
||||
echo -e "${GREEN}PM2 service '$service_name' stopped and removed${NC}"
|
||||
|
||||
# Remove from registry
|
||||
remove_service_from_registry "$service_name"
|
||||
else
|
||||
echo -e "${YELLOW}PM2 service '$service_name' not found or already removed${NC}"
|
||||
# Still try to remove from registry in case it's orphaned
|
||||
remove_service_from_registry "$service_name"
|
||||
fi
|
||||
|
||||
return 0
|
||||
@@ -391,6 +585,7 @@ function pm2_service_logs() {
|
||||
# Systemd service management functions
|
||||
function get_systemd_dir() {
|
||||
local type="$1"
|
||||
|
||||
if [ "$type" = "--system" ]; then
|
||||
echo "/etc/systemd/system"
|
||||
else
|
||||
@@ -403,17 +598,32 @@ function systemd_create_service() {
|
||||
local command="$2"
|
||||
local restart_policy="$3"
|
||||
local systemd_type="--user"
|
||||
local bin_path=""
|
||||
local gdb_enabled="0"
|
||||
local server_config=""
|
||||
shift 3
|
||||
|
||||
check_systemd || return 1
|
||||
|
||||
# Parse systemd type
|
||||
# Parse systemd type and extract additional parameters
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--system|--user)
|
||||
systemd_type="$1"
|
||||
shift
|
||||
;;
|
||||
--bin-path)
|
||||
bin_path="$2"
|
||||
shift 2
|
||||
;;
|
||||
--gdb-enabled)
|
||||
gdb_enabled="$2"
|
||||
shift 2
|
||||
;;
|
||||
--server-config)
|
||||
server_config="$2"
|
||||
shift 2
|
||||
;;
|
||||
*)
|
||||
command+=" $1"
|
||||
shift
|
||||
@@ -421,6 +631,18 @@ function systemd_create_service() {
|
||||
esac
|
||||
done
|
||||
|
||||
# If bin_path is not provided, try to extract from command
|
||||
if [ -z "$bin_path" ]; then
|
||||
# Try to extract bin path from run-engine command
|
||||
if [[ "$command" =~ run-engine[[:space:]]+start[[:space:]]+([^[:space:]]+) ]]; then
|
||||
local binary_path="${BASH_REMATCH[1]}"
|
||||
bin_path="$(dirname "$binary_path")"
|
||||
else
|
||||
# Fallback to current directory
|
||||
bin_path="$(pwd)"
|
||||
fi
|
||||
fi
|
||||
|
||||
local systemd_dir=$(get_systemd_dir "$systemd_type")
|
||||
local service_file="$systemd_dir/$service_name.service"
|
||||
|
||||
@@ -457,6 +679,11 @@ function systemd_create_service() {
|
||||
# Create service file
|
||||
echo -e "${YELLOW}Creating systemd service: $service_name${NC}"
|
||||
|
||||
# Ensure bin_path is absolute
|
||||
if [[ ! "$bin_path" = /* ]]; then
|
||||
bin_path="$(realpath "$bin_path")"
|
||||
fi
|
||||
|
||||
if [ "$systemd_type" = "--system" ]; then
|
||||
# System service template (with User directive)
|
||||
cat > "$service_file" << EOF
|
||||
@@ -471,7 +698,7 @@ Restart=$restart_policy
|
||||
RestartSec=3
|
||||
User=$(whoami)
|
||||
Group=$(id -gn)
|
||||
WorkingDirectory=$(realpath "$bin_path")
|
||||
WorkingDirectory=$bin_path
|
||||
StandardOutput=journal+console
|
||||
StandardError=journal+console
|
||||
|
||||
@@ -490,7 +717,7 @@ Type=${service_type}
|
||||
ExecStart=$command
|
||||
Restart=$restart_policy
|
||||
RestartSec=3
|
||||
WorkingDirectory=$(realpath "$bin_path")
|
||||
WorkingDirectory=$bin_path
|
||||
StandardOutput=journal+console
|
||||
StandardError=journal+console
|
||||
|
||||
@@ -498,10 +725,6 @@ StandardError=journal+console
|
||||
WantedBy=default.target
|
||||
EOF
|
||||
fi
|
||||
|
||||
if [ "$systemd_type" = "--system" ]; then
|
||||
sed -i 's/WantedBy=default.target/WantedBy=multi-user.target/' "$service_file"
|
||||
fi
|
||||
|
||||
# Reload systemd and enable service
|
||||
if [ "$systemd_type" = "--system" ]; then
|
||||
@@ -513,6 +736,10 @@ EOF
|
||||
fi
|
||||
|
||||
echo -e "${GREEN}Systemd service '$service_name' created successfully${NC}"
|
||||
|
||||
# Add to registry
|
||||
add_service_to_registry "$service_name" "systemd" "service" "$command" "" "$systemd_type" "$restart_policy" "$session_manager" "$gdb_enabled" "" "$server_config"
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
@@ -572,6 +799,10 @@ function systemd_remove_service() {
|
||||
if [ "$removal_failed" = "true" ]; then
|
||||
echo -e "${YELLOW}Note: Service may still be running but configuration was removed${NC}"
|
||||
fi
|
||||
|
||||
# Remove from registry
|
||||
remove_service_from_registry "$service_name"
|
||||
|
||||
return 0
|
||||
else
|
||||
echo -e "${RED}Failed to remove systemd service file '$service_file'${NC}"
|
||||
@@ -659,7 +890,7 @@ function create_service() {
|
||||
|
||||
# Default values for run-engine configuration
|
||||
local provider="auto"
|
||||
local bin_path="$BINPATH/bin" # get from config or environment
|
||||
local bin_path="${BINPATH:-$ROOT_DIR/bin}" # get from config or environment
|
||||
local server_config=""
|
||||
local session_manager="none"
|
||||
local gdb_enabled="0"
|
||||
@@ -839,8 +1070,6 @@ EOF
|
||||
|
||||
# Check if service creation was successful
|
||||
if [ "$service_creation_success" = "true" ]; then
|
||||
# Register the service
|
||||
register_service "$service_name" "$provider" "$service_type"
|
||||
echo -e "${GREEN}Service '$service_name' created successfully${NC}"
|
||||
echo -e "${BLUE}Run-engine config: $run_engine_config${NC}"
|
||||
|
||||
@@ -880,14 +1109,20 @@ function update_service() {
|
||||
# Extract service information
|
||||
local provider=$(echo "$service_info" | jq -r '.provider')
|
||||
local service_type=$(echo "$service_info" | jq -r '.type')
|
||||
local config_file=$(echo "$service_info" | jq -r '.config')
|
||||
local config_file="$CONFIG_DIR/$service_name.conf"
|
||||
|
||||
# Load current configuration
|
||||
if [ ! -f "$config_file" ]; then
|
||||
echo -e "${RED}Error: Service configuration file not found: $config_file${NC}"
|
||||
return 1
|
||||
fi
|
||||
source "$config_file"
|
||||
|
||||
# Load current run-engine configuration
|
||||
if [ -f "$RUN_ENGINE_CONFIG_FILE" ]; then
|
||||
source "$RUN_ENGINE_CONFIG_FILE"
|
||||
else
|
||||
echo -e "${YELLOW}Warning: Run-engine configuration file not found: $RUN_ENGINE_CONFIG_FILE${NC}"
|
||||
fi
|
||||
|
||||
# Parse options to update
|
||||
@@ -1020,11 +1255,13 @@ function delete_service() {
|
||||
|
||||
# Extract provider and config
|
||||
local provider=$(echo "$service_info" | jq -r '.provider')
|
||||
local config_file=$(echo "$service_info" | jq -r '.config')
|
||||
local config_file="$CONFIG_DIR/$service_name.conf"
|
||||
|
||||
# Load configuration to get run-engine config file
|
||||
if [ -f "$config_file" ]; then
|
||||
source "$config_file"
|
||||
else
|
||||
echo -e "${YELLOW}Warning: Service configuration file not found: $config_file${NC}"
|
||||
fi
|
||||
|
||||
echo -e "${YELLOW}Deleting service '$service_name' (provider: $provider)...${NC}"
|
||||
@@ -1048,8 +1285,9 @@ function delete_service() {
|
||||
echo -e "${GREEN}Removed run-engine config: $RUN_ENGINE_CONFIG_FILE${NC}"
|
||||
fi
|
||||
|
||||
# Unregister service
|
||||
unregister_service "$service_name"
|
||||
# Remove configuration file
|
||||
rm -f "$config_file"
|
||||
|
||||
echo -e "${GREEN}Service '$service_name' deleted successfully${NC}"
|
||||
else
|
||||
echo -e "${RED}Failed to remove service '$service_name' from $provider${NC}"
|
||||
@@ -1166,7 +1404,7 @@ function edit_config() {
|
||||
fi
|
||||
|
||||
# Get configuration file path
|
||||
local config_file=$(echo "$service_info" | jq -r '.config')
|
||||
local config_file="$CONFIG_DIR/$service_name.conf"
|
||||
|
||||
# Load configuration to get run-engine config file
|
||||
source "$config_file"
|
||||
@@ -1191,7 +1429,7 @@ function attach_to_service() {
|
||||
|
||||
# Extract provider
|
||||
local provider=$(echo "$service_info" | jq -r '.provider')
|
||||
local config_file=$(echo "$service_info" | jq -r '.config')
|
||||
local config_file="$CONFIG_DIR/$service_name.conf"
|
||||
|
||||
# Load configuration to get run-engine config file
|
||||
if [ ! -f "$config_file" ]; then
|
||||
@@ -1206,6 +1444,11 @@ function attach_to_service() {
|
||||
echo -e "${RED}Error: Run-engine configuration file not found: $RUN_ENGINE_CONFIG_FILE${NC}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ ! -f "$RUN_ENGINE_CONFIG_FILE" ]; then
|
||||
echo -e "${RED}Error: Run-engine configuration file not found: $RUN_ENGINE_CONFIG_FILE${NC}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
source "$RUN_ENGINE_CONFIG_FILE"
|
||||
|
||||
@@ -1264,9 +1507,22 @@ function attach_interactive_shell() {
|
||||
|
||||
# For systemd without session manager, show helpful message
|
||||
local service_info=$(get_service_info "$service_name")
|
||||
local config_file=$(echo "$service_info" | jq -r '.config')
|
||||
local config_file="$CONFIG_DIR/$service_name.conf"
|
||||
|
||||
# Check if config file exists before sourcing
|
||||
if [ ! -f "$config_file" ]; then
|
||||
echo -e "${RED}Error: Service configuration file not found: $config_file${NC}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
source "$config_file"
|
||||
|
||||
# Check if RUN_ENGINE_CONFIG_FILE exists before sourcing
|
||||
if [ ! -f "$RUN_ENGINE_CONFIG_FILE" ]; then
|
||||
echo -e "${RED}Error: Run-engine configuration file not found: $RUN_ENGINE_CONFIG_FILE${NC}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
source "$RUN_ENGINE_CONFIG_FILE"
|
||||
|
||||
echo -e "${RED}Error: Cannot attach to systemd service '$service_name'${NC}"
|
||||
@@ -1375,6 +1631,9 @@ case "${1:-help}" in
|
||||
list)
|
||||
list_services "$2"
|
||||
;;
|
||||
restore)
|
||||
restore_missing_services
|
||||
;;
|
||||
start|stop|restart|status)
|
||||
if [ $# -lt 2 ]; then
|
||||
echo -e "${RED}Error: Service name required for $1 command${NC}"
|
||||
|
||||
Reference in New Issue
Block a user