376 lines
14 KiB
Bash
376 lines
14 KiB
Bash
#!/bin/bash
|
|
# New Setuper script for A/D Infrastructure
|
|
# Downloads Packmate, moded_distructive_farm, Firegex OUTSIDE SERVICES_DIR, starts them, then starts all game services from SERVICES_DIR, and registers only Packmate and Firegex with controller.
|
|
|
|
set +e
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
ROOT_DIR="$SCRIPT_DIR/.."
|
|
|
|
# Read .env for SERVICES_DIR, CONTROLLER_API, SECRET_TOKEN
|
|
ENV_FILE="$ROOT_DIR/.env"
|
|
if [ ! -f "$ENV_FILE" ]; then
|
|
echo ".env file not found in $ROOT_DIR. Exiting."
|
|
exit 1
|
|
fi
|
|
|
|
SERVICES_DIR=$(grep '^SERVICES_DIR=' "$ENV_FILE" | cut -d'=' -f2- | tr -d '"' | xargs)
|
|
CONTROLLER_API=$(grep '^CONTROLLER_API=' "$ENV_FILE" | cut -d'=' -f2- | tr -d '"' | xargs)
|
|
SECRET_TOKEN=$(grep '^SECRET_TOKEN=' "$ENV_FILE" | cut -d'=' -f2- | tr -d '"' | xargs)
|
|
|
|
# Defaults
|
|
if [ -z "$CONTROLLER_API" ]; then
|
|
CONTROLLER_API="http://localhost:8001"
|
|
fi
|
|
if [ -z "$SECRET_TOKEN" ]; then
|
|
SECRET_TOKEN="change-me-in-production"
|
|
fi
|
|
|
|
echo "=== A/D Infrastructure Setuper (NEW) ==="
|
|
echo "Game services directory: $SERVICES_DIR"
|
|
echo ""
|
|
|
|
# Function to call controller API
|
|
call_api() {
|
|
local endpoint="$1"
|
|
local method="${2:-GET}"
|
|
local data="${3:-}"
|
|
if [ "$method" = "POST" ]; then
|
|
curl -s -X POST "$CONTROLLER_API$endpoint" \
|
|
-H "Authorization: Bearer $SECRET_TOKEN" \
|
|
-H "Content-Type: application/json" \
|
|
-d "$data"
|
|
else
|
|
curl -s "$CONTROLLER_API$endpoint" \
|
|
-H "Authorization: Bearer $SECRET_TOKEN"
|
|
fi
|
|
}
|
|
|
|
# Function to setup and start Packmate
|
|
setup_packmate() {
|
|
echo "=== Setting up Packmate ==="
|
|
local packmate_dir="$ROOT_DIR/packmate"
|
|
if [ -d "$packmate_dir" ]; then
|
|
echo "Packmate directory already exists, updating..."
|
|
cd "$packmate_dir"
|
|
git pull
|
|
git submodule update --init --recursive
|
|
else
|
|
echo "Cloning Packmate with submodules..."
|
|
git clone --recursive https://gitlab.com/packmate/Packmate.git "$packmate_dir"
|
|
cd "$packmate_dir"
|
|
fi
|
|
mkdir -p pcaps rsa_keys Packmate_stuff
|
|
# Read config from parent .env
|
|
BOARD_URL=$(grep '^BOARD_URL=' "$ENV_FILE" | cut -d'=' -f2- | tr -d '"' | xargs)
|
|
PACKMATE_LOCAL_IP=$(grep '^PACKMATE_LOCAL_IP=' "$ENV_FILE" | cut -d'=' -f2- | tr -d '"' | xargs)
|
|
NET_INTERFACE=$(grep '^NET_INTERFACE=' "$ENV_FILE" | cut -d'=' -f2- | tr -d '"' | xargs)
|
|
PACKMATE_WEB_LOGIN=$(grep '^PACKMATE_WEB_LOGIN=' "$ENV_FILE" | cut -d'=' -f2- | tr -d '"' | xargs)
|
|
PACKMATE_WEB_PASSWORD=$(grep '^PACKMATE_WEB_PASSWORD=' "$ENV_FILE" | cut -d'=' -f2- | tr -d '"' | xargs)
|
|
# Defaults if not set
|
|
if [ -z "$PACKMATE_LOCAL_IP" ]; then
|
|
PACKMATE_LOCAL_IP="10.60.1.2"
|
|
fi
|
|
if [ -z "$NET_INTERFACE" ]; then
|
|
NET_INTERFACE="eth0"
|
|
fi
|
|
if [ -z "$PACKMATE_WEB_LOGIN" ]; then
|
|
PACKMATE_WEB_LOGIN="admin"
|
|
fi
|
|
if [ -z "$PACKMATE_WEB_PASSWORD" ]; then
|
|
PACKMATE_WEB_PASSWORD="admin123"
|
|
fi
|
|
# .env and config generation (minimal)
|
|
cat > .env <<ENVEOF
|
|
BUILD_TAG=latest
|
|
PACKMATE_DB_PASSWORD=K604YnL3G1hp2RDkCZNjGpxbyNpNHTRb
|
|
NET_INTERFACE=$NET_INTERFACE
|
|
PACKMATE_LOCAL_IP=$PACKMATE_LOCAL_IP
|
|
WEB_LOGIN=$PACKMATE_WEB_LOGIN
|
|
WEB_PASSWORD=$PACKMATE_WEB_PASSWORD
|
|
POSTGRES_USER=packmate
|
|
POSTGRES_PASSWORD=K604YnL3G1hp2RDkCZNjGpxbyNpNHTRb
|
|
POSTGRES_DB=packmate
|
|
DB_PASSWORD=K604YnL3G1hp2RDkCZNjGpxbyNpNHTRb
|
|
INTERFACE=$NET_INTERFACE
|
|
LOCAL_IP=$PACKMATE_LOCAL_IP
|
|
MODE=LIVE
|
|
OLD_STREAMS_CLEANUP_ENABLED=true
|
|
OLD_STREAMS_CLEANUP_INTERVAL=5
|
|
OLD_STREAMS_CLEANUP_THRESHOLD=240
|
|
ENVEOF
|
|
cat > Packmate_stuff/postgresql.conf <<'PGEOF'
|
|
port = 65001
|
|
max_connections = 100
|
|
shared_buffers = 128MB
|
|
PGEOF
|
|
cat > Packmate_stuff/update_db_config.sh <<'SHEOF'
|
|
#!/bin/bash
|
|
cp /tmp/postgresql.conf /var/lib/postgresql/data/postgresql.conf
|
|
SHEOF
|
|
chmod +x Packmate_stuff/update_db_config.sh
|
|
# docker-compose.yml (minimal)
|
|
cat > docker-compose.yml <<'DCEOF'
|
|
services:
|
|
packmate:
|
|
env_file:
|
|
- .env
|
|
container_name: packmate-app
|
|
network_mode: "host"
|
|
image: registry.gitlab.com/packmate/packmate:latest
|
|
volumes:
|
|
- "./pcaps/:/app/pcaps/:ro"
|
|
- "./rsa_keys/:/app/rsa_keys/:ro"
|
|
depends_on:
|
|
db:
|
|
condition: service_healthy
|
|
db:
|
|
container_name: packmate-db
|
|
env_file:
|
|
- .env
|
|
network_mode: "host"
|
|
image: postgres:15.2
|
|
volumes:
|
|
- "./Packmate_stuff/postgresql.conf:/tmp/postgresql.conf:ro"
|
|
- "./Packmate_stuff/update_db_config.sh:/docker-entrypoint-initdb.d/_update_db_config.sh:ro"
|
|
healthcheck:
|
|
test: [ "CMD-SHELL", "pg_isready -U packmate -p 65001" ]
|
|
interval: 2s
|
|
timeout: 5s
|
|
retries: 15
|
|
DCEOF
|
|
echo "Starting Packmate containers..."
|
|
docker compose up -d --no-build
|
|
echo "Waiting for Packmate to be ready..."
|
|
sleep 5
|
|
cd "$SCRIPT_DIR"
|
|
}
|
|
|
|
# Function to setup and start moded_distructive_farm
|
|
setup_farm() {
|
|
echo "=== Setting up moded_distructive_farm ==="
|
|
local farm_dir="$ROOT_DIR/moded_distructive_farm"
|
|
if [ -d "$farm_dir" ]; then
|
|
echo "Farm directory already exists, updating..."
|
|
cd "$farm_dir"
|
|
git pull
|
|
else
|
|
echo "Cloning moded_distructive_farm..."
|
|
git clone https://github.com/ilyastar9999/moded_distructive_farm.git "$farm_dir"
|
|
cd "$farm_dir"
|
|
fi
|
|
# Read config from parent .env
|
|
BOARD_URL=$(grep '^BOARD_URL=' "$ENV_FILE" | cut -d'=' -f2- | tr -d '"' | xargs)
|
|
TEAM_TOKEN=$(grep '^TEAM_TOKEN=' "$ENV_FILE" | cut -d'=' -f2- | tr -d '"' | xargs)
|
|
NUM_TEAMS=$(grep '^NUM_TEAMS=' "$ENV_FILE" | cut -d'=' -f2- | tr -d '"' | xargs)
|
|
IP_TEAM_BASE=$(grep '^IP_TEAM_BASE=' "$ENV_FILE" | cut -d'=' -f2- | tr -d '"' | xargs)
|
|
cat > .env <<ENVEOF
|
|
DB_PORT=5432
|
|
DB_HOST=postgres
|
|
DB_USER=farm
|
|
DB_PASS=farmpassword123
|
|
DB_NAME=farm
|
|
BOARD_URL=$BOARD_URL
|
|
TEAM_TOKEN=$TEAM_TOKEN
|
|
WEB_PASSWORD=farmadmin
|
|
NUM_TEAMS=$NUM_TEAMS
|
|
IP_TEAM_BASE=$IP_TEAM_BASE
|
|
API_TOKEN=farm-api-token-123
|
|
POSTGRES_USER=farm
|
|
POSTGRES_PASSWORD=farmpassword123
|
|
POSTGRES_DB=farm
|
|
ENVEOF
|
|
echo "Starting moded_distructive_farm containers..."
|
|
docker compose up -d --no-build
|
|
cd "$SCRIPT_DIR"
|
|
}
|
|
|
|
# Function to setup and start Firegex
|
|
setup_firegex() {
|
|
echo "=== Setting up Firegex ==="
|
|
local firegex_dir="$ROOT_DIR/firegex"
|
|
|
|
# Read config from parent .env
|
|
BOARD_URL=$(grep '^BOARD_URL=' "$ENV_FILE" | cut -d'=' -f2- | tr -d '"' | xargs)
|
|
TEAM_TOKEN=$(grep '^TEAM_TOKEN=' "$ENV_FILE" | cut -d'=' -f2- | tr -d '"' | xargs)
|
|
|
|
# Export environment variables for installer
|
|
export SCOREBOARD_URL="$BOARD_URL"
|
|
export TEAM_TOKEN="$TEAM_TOKEN"
|
|
export FIREGEX_PORT="5000"
|
|
export DOCKER_MODE="true"
|
|
|
|
echo "Installing Firegex using official installer..."
|
|
sh -c "$(curl -sLf https://pwnzer0tt1.it/firegex.sh)"
|
|
|
|
cd "$SCRIPT_DIR"
|
|
}
|
|
|
|
# Start all game services from SERVICES_DIR
|
|
start_game_services() {
|
|
echo "=== Starting all game services from $SERVICES_DIR ==="
|
|
|
|
# Read Packmate config from .env
|
|
PACKMATE_LOCAL_IP=$(grep '^PACKMATE_LOCAL_IP=' "$ENV_FILE" | cut -d'=' -f2- | tr -d '"' | xargs)
|
|
PACKMATE_WEB_LOGIN=$(grep '^PACKMATE_WEB_LOGIN=' "$ENV_FILE" | cut -d'=' -f2- | tr -d '"' | xargs)
|
|
PACKMATE_WEB_PASSWORD=$(grep '^PACKMATE_WEB_PASSWORD=' "$ENV_FILE" | cut -d'=' -f2- | tr -d '"' | xargs)
|
|
if [ -z "$PACKMATE_LOCAL_IP" ]; then
|
|
PACKMATE_LOCAL_IP="10.60.1.2"
|
|
fi
|
|
if [ -z "$PACKMATE_WEB_LOGIN" ]; then
|
|
PACKMATE_WEB_LOGIN="admin"
|
|
fi
|
|
if [ -z "$PACKMATE_WEB_PASSWORD" ]; then
|
|
PACKMATE_WEB_PASSWORD="admin123"
|
|
fi
|
|
|
|
echo "Preparing to start game services..."
|
|
# Create base64 auth string
|
|
PACKMATE_AUTH=$(echo -n "$PACKMATE_WEB_LOGIN:$PACKMATE_WEB_PASSWORD" | base64)
|
|
PACKMATE_URL="http://${PACKMATE_LOCAL_IP}:65000"
|
|
# Try to obtain Packmate session cookie (JSESSIONID) using Basic auth
|
|
PACKMATE_COOKIE=$(curl -s -k -D - "$PACKMATE_URL/" \
|
|
-H "Authorization: Basic $PACKMATE_AUTH" \
|
|
-H "Accept: application/json" | grep -i 'Set-Cookie' | grep -i 'JSESSIONID' | head -n1 | sed 's/.*JSESSIONID=\([^;]*\).*/\1/')
|
|
if [ -n "$PACKMATE_COOKIE" ]; then
|
|
PACKMATE_COOKIE_HEADER="Cookie: JSESSIONID=$PACKMATE_COOKIE"
|
|
else
|
|
PACKMATE_COOKIE_HEADER=""
|
|
fi
|
|
|
|
# Resolve SERVICES_DIR to absolute path
|
|
case "$SERVICES_DIR" in
|
|
/*)
|
|
# Already absolute path
|
|
;;
|
|
*)
|
|
# Relative path, make it absolute
|
|
SERVICES_DIR="$ROOT_DIR/$SERVICES_DIR"
|
|
;;
|
|
esac
|
|
|
|
if [ ! -d "$SERVICES_DIR" ]; then
|
|
echo "Services directory $SERVICES_DIR does not exist, skipping game services startup."
|
|
return
|
|
fi
|
|
|
|
# Find all subdirectories with docker-compose.yml
|
|
echo "Scanning for services in $SERVICES_DIR..."
|
|
local service_count=0
|
|
|
|
for service_dir in "$SERVICES_DIR"/*/ ; do
|
|
# Skip if wildcard didn't match anything
|
|
if [ ! -d "$service_dir" ]; then
|
|
continue
|
|
fi
|
|
|
|
if [ -f "$service_dir/docker-compose.yml" ] || [ -f "$service_dir/docker-compose.yaml" ]; then
|
|
service_name=$(basename "$service_dir")
|
|
echo "Starting service: $service_name"
|
|
|
|
# Get relative path from SERVICES_DIR
|
|
service_rel_path=$(basename "$service_dir")
|
|
|
|
cd "$service_dir"
|
|
docker compose up -d
|
|
|
|
# Determine which compose file exists
|
|
compose_file="docker-compose.yml"
|
|
if [ ! -f "$compose_file" ] && [ -f "docker-compose.yaml" ]; then
|
|
compose_file="docker-compose.yaml"
|
|
fi
|
|
if [ ! -f "$compose_file" ] && [ -f "compose.yml" ]; then
|
|
compose_file="compose.yml"
|
|
fi
|
|
|
|
# Get actual exposed ports from docker ps, excluding 3333, 4444, 65000, 65001, 5432
|
|
container_name="${service_name}-app"
|
|
service_ports=$(docker ps --filter "name=$container_name" --format "{{.Ports}}" | grep -oE '[0-9]+->' | sed 's/->//' | grep -Ev '^(3333|4444|65000|65001|5432)$' | tr '\n' ',' | sed 's/,$//')
|
|
echo "Exposed ports for $service_name: $service_ports"
|
|
|
|
# Register service with controller and send ports, except for Firegex, farm, and packmate
|
|
if [ "$service_name" != "firegex" ] && [ "$service_name" != "farm" ] && [ "$service_name" != "packmate" ]; then
|
|
echo "Registering $service_name with controller..."
|
|
ports_json="[$service_ports]"
|
|
ports_json=$(echo "$ports_json" | sed 's/,/,/g')
|
|
call_api "/services" "POST" "{\"name\": \"$service_name\", \"path\": \"$service_rel_path\", \"ports\": $ports_json}"
|
|
else
|
|
echo "Skipping controller registration for $service_name."
|
|
fi
|
|
|
|
# Add service to Packmate if Packmate is running
|
|
if [ -n "$service_ports" ]; then
|
|
echo "Adding $service_name to Packmate..."
|
|
# Try to add each exposed host port to Packmate
|
|
echo "$service_ports" | tr ',' '\n' | while read port; do
|
|
if [ -n "$port" ]; then
|
|
# Primary attempt (with trailing slash)
|
|
status=$(curl -s -k -o /dev/null -w "%{http_code}" -X POST "${PACKMATE_URL}/api/service/" \
|
|
-H "Accept: application/json" \
|
|
-H "Authorization: Basic $PACKMATE_AUTH" \
|
|
-H "Content-Type: application/json" \
|
|
${PACKMATE_COOKIE_HEADER:+-H "$PACKMATE_COOKIE_HEADER"} \
|
|
-d "{\"name\": \"$service_name\", \"port\": $port}" )
|
|
if [ "$status" -ge 200 ] && [ "$status" -lt 300 ]; then
|
|
echo "Packmate: registered $service_name port $port (status $status)"
|
|
else
|
|
# Fallback attempt without trailing slash
|
|
status2=$(curl -s -k -o /dev/null -w "%{http_code}" -X POST "${PACKMATE_URL}/api/service" \
|
|
-H "Accept: application/json" \
|
|
-H "Authorization: Basic $PACKMATE_AUTH" \
|
|
-H "Content-Type: application/json" \
|
|
${PACKMATE_COOKIE_HEADER:+-H "$PACKMATE_COOKIE_HEADER"} \
|
|
-d "{\"name\": \"$service_name\", \"port\": $port}" )
|
|
echo "Packmate: register $service_name port $port -> status $status (fallback $status2)"
|
|
fi
|
|
fi
|
|
done
|
|
fi
|
|
|
|
service_count=$((service_count + 1))
|
|
fi
|
|
done
|
|
|
|
echo "Started and registered $service_count game service(s)"
|
|
|
|
cd "$SCRIPT_DIR"
|
|
}
|
|
|
|
# Start infrastructure services (controller, web, telegram bot, scoreboard injector)
|
|
start_infrastructure_services() {
|
|
echo "Starting infrastructure services..."
|
|
docker compose -f "$ROOT_DIR/docker-compose.yaml" up -d --build
|
|
echo "Infrastructure services started."
|
|
}
|
|
|
|
# Main setup flow
|
|
main() {
|
|
echo "Starting setup process..."
|
|
echo ""
|
|
read -p "Setup Packmate? (y/n): " setup_pm
|
|
read -p "Setup moded_distructive_farm? (y/n): " setup_fm
|
|
read -p "Setup Firegex? (y/n): " setup_fg
|
|
echo ""
|
|
if [ "$setup_pm" != "n" ]; then
|
|
setup_packmate
|
|
fi
|
|
if [ "$setup_fm" != "n" ]; then
|
|
setup_farm
|
|
fi
|
|
if [ "$setup_fg" != "n" ]; then
|
|
setup_firegex
|
|
fi
|
|
start_infrastructure_services
|
|
start_game_services
|
|
echo ""
|
|
echo "=== Setup Complete! ==="
|
|
echo "Game services have been started from: $SERVICES_DIR"
|
|
echo ""
|
|
echo "Next steps:"
|
|
echo " 1. Access web dashboard: http://localhost:8000"
|
|
echo " 2. Register services via the dashboard if auto-registration failed"
|
|
echo ""
|
|
}
|
|
|
|
main
|