Add gameadm: Modulares Game Server Administration System

- Ersetzt rustadm mit erweiterbarem, modulararem Design
- Unterstützt Rust Server und Minecraft Server (Beispiel)
- Zentrale Verwaltung durch /usr/local/bin/gameadm
- Module in /etc/gameadm/modules/ für verschiedene Spiele
- Farbige Ausgabe und robuste Fehlerbehandlung
- Vollständige Dokumentation mit Migrations- und Entwicklungshinweisen
This commit is contained in:
Automation User 2025-08-14 21:17:23 +00:00
parent 7bbe580837
commit 73b4a397d1
4 changed files with 676 additions and 0 deletions

239
gameadm/README.md Normal file
View File

@ -0,0 +1,239 @@
# gameadm - Modularer Game Server Administrator
## Übersicht
`gameadm` ist ein modulares System zur Verwaltung verschiedener Game Server, das das ursprüngliche `rustadm` Skript ersetzt und für zukünftige Spiele erweiterbar ist.
## Architektur
```
gameadm (Hauptskript)
├── /etc/gameadm/
│ ├── modules/ # Spielmodule
│ │ ├── rust.sh # Rust Server Modul
│ │ ├── mc.sh # Minecraft Server Modul
│ │ └── ... # Weitere Module
│ └── README.md # Diese Dokumentation
└── /usr/local/bin/gameadm # Ausführbares Hauptskript
```
## Verwendung
### Grundlegende Syntax
```bash
gameadm <spiel> <befehl> [optionen]
```
### Verfügbare Spiele
- **rust** - Rust Game Server (vollständig funktional)
- **mc** - Minecraft Server (Beispiel-Modul)
### Verfügbare Befehle (pro Spiel)
- `start` - Startet den Server
- `stop` - Stoppt den Server
- `restart` - Startet Server neu
- `status` - Zeigt Server-Status
- `logs` - Zeigt Server-Logs
- `follow` - Folgt Logs in Echtzeit
- `update` - Aktualisiert Server-Image
- `help` - Zeigt Hilfe für das Spiel
### Beispiele
```bash
# Rust Server verwalten
gameadm rust start
gameadm rust status
gameadm rust logs
gameadm rust stop
# Minecraft Server verwalten (zukünftig)
gameadm mc start
gameadm mc status
# Hilfe anzeigen
gameadm --help
gameadm rust help
gameadm list
```
## Module erstellen
### Neues Spiel hinzufügen
1. **Modul-Datei erstellen:**
```bash
sudo nano /etc/gameadm/modules/neuespiel.sh
```
2. **Grundstruktur implementieren:**
```bash
#!/bin/bash
# Neues Spiel Modul für gameadm
# Konfiguration laden
CONFIG_FILE="/etc/neuespiel-server.conf"
if [[ -f "$CONFIG_FILE" ]]; then
source "$CONFIG_FILE"
fi
# Standardwerte
CONTAINER_NAME=${CONTAINER_NAME:-neuespiel-server}
IMAGE=${IMAGE:-docker.io/beispiel/neuespiel:latest}
DATA_DIR=${DATA_DIR:-/srv/neuespiel}
PORT=${PORT:-12345}
# Hilfsfunktionen
is_running() {
podman inspect -f '{{.State.Running}}' "$CONTAINER_NAME" 2>/dev/null | grep -q true
}
# Befehle implementieren
cmd_start() {
# Start-Logik hier
}
cmd_stop() {
# Stop-Logik hier
}
# Weitere Befehle...
```
3. **Ausführbar machen:**
```bash
sudo chmod +x /etc/gameadm/modules/neuespiel.sh
```
### Erforderliche Funktionen
Jedes Modul muss folgende Funktionen implementieren:
- `cmd_start()` - Server starten
- `cmd_stop()` - Server stoppen
- `cmd_status()` - Status anzeigen
- `cmd_logs()` - Logs anzeigen
- `cmd_help()` - Hilfe anzeigen
Optionale Funktionen:
- `cmd_restart()` - Server neu starten
- `cmd_follow()` - Logs folgen
- `cmd_update()` - Image aktualisieren
## Konfiguration
### Rust Server
- **Datei:** `/etc/rust-server.conf`
- **Beispiel:**
```bash
CONTAINER_NAME=rust-game
IMAGE=docker.io/didstopia/rust-server:latest
DATA_DIR=/srv/rust
PORT=28015
RCON_PORT=28016
MAXPLAYERS=4
RUST_SERVER_NAME="Mein Rust Server"
```
### Minecraft Server
- **Datei:** `/etc/minecraft-server.conf`
- **Beispiel:**
```bash
CONTAINER_NAME=minecraft-server
IMAGE=docker.io/itzg/minecraft-server:latest
DATA_DIR=/srv/minecraft
PORT=25565
MEMORY_LIMIT=2g
VERSION=LATEST
```
## Migration von rustadm
### Vor der Migration
```bash
# Backup der alten Konfiguration
sudo cp /etc/rust-server.conf /etc/rust-server.conf.backup
# Backup des alten Skripts
sudo cp /usr/local/bin/rustadm /usr/local/bin/rustadm.backup
```
### Nach der Migration
```bash
# Alte Befehle durch neue ersetzen
rustadm start → gameadm rust start
rustadm stop → gameadm rust stop
rustadm status → gameadm rust status
rustadm logs → gameadm rust logs
```
## Vorteile der neuen Architektur
1. **Modularität** - Einfaches Hinzufügen neuer Spiele
2. **Wartbarkeit** - Zentrale Logik im Hauptskript
3. **Konsistenz** - Einheitliche Befehle für alle Spiele
4. **Erweiterbarkeit** - Neue Befehle pro Spiel möglich
5. **Farbige Ausgabe** - Bessere Benutzerfreundlichkeit
6. **Fehlerbehandlung** - Robuste Fehlerbehandlung
7. **Dokumentation** - Integrierte Hilfe für alle Module
## Troubleshooting
### Modul wird nicht gefunden
```bash
# Berechtigungen prüfen
ls -la /etc/gameadm/modules/
# Modul ausführbar machen
sudo chmod +x /etc/gameadm/modules/meinspiel.sh
```
### Fehler beim Laden des Moduls
```bash
# Syntax prüfen
bash -n /etc/gameadm/modules/meinspiel.sh
# Debug-Ausgabe aktivieren
bash -x /etc/gameadm/modules/meinspiel.sh
```
### Container-Probleme
```bash
# Podman-Status prüfen
podman ps -a
# Container-Logs direkt anzeigen
podman logs meinspiel-server
```
## Entwicklung
### Neue Befehle hinzufügen
1. **Im Modul neue Funktion erstellen:**
```bash
cmd_neuerbefehl() {
log "INFO" "Führe neuen Befehl aus..."
# Implementierung hier
}
```
2. **Hilfe aktualisieren:**
```bash
cmd_help() {
cat <<EOF
...
neuerbefehl - Beschreibung des neuen Befehls
...
EOF
}
```
### Gemeinsame Funktionen
Das Hauptskript stellt folgende Funktionen zur Verfügung:
- `log(level, message)` - Logging mit Farben
- `show_help()` - Globale Hilfe
- `load_game_module(game)` - Modul laden
## Lizenz
Dieses Projekt folgt den gleichen Lizenzbedingungen wie das ursprüngliche System.

137
gameadm/bin/gameadm Executable file
View File

@ -0,0 +1,137 @@
#!/bin/bash
set -euo pipefail
# gameadm - Modularer Game Server Administrator
# Ersetzt rustadm und ist für verschiedene Spiele erweiterbar
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
GAMEADM_DIR="/etc/gameadm"
MODULES_DIR="$GAMEADM_DIR/modules"
# Farben für bessere Ausgabe
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Logging-Funktion
log() {
local level="$1"
shift
local message="$*"
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
case "$level" in
"INFO") echo -e "${GREEN}[gameadm]${NC} $message" ;;
"WARN") echo -e "${YELLOW}[gameadm]${NC} $message" ;;
"ERROR") echo -e "${RED}[gameadm]${NC} $message" ;;
"DEBUG") echo -e "${BLUE}[gameadm]${NC} $message" ;;
esac
}
# Hilfsfunktionen
show_help() {
cat <<EOF
gameadm - Modularer Game Server Administrator
Verwendung:
gameadm <spiel> <befehl> [optionen]
Verfügbare Spiele:
rust - Rust Game Server
mc - Minecraft Server (zukünftig)
# Weitere Spiele können hier hinzugefügt werden
Verfügbare Befehle (pro Spiel):
start - Startet den Server
stop - Stoppt den Server
restart - Startet den Server neu
status - Zeigt Server-Status
logs - Zeigt Server-Logs
follow - Folgt Logs in Echtzeit
update - Aktualisiert Server-Image
help - Zeigt Hilfe für das Spiel
Beispiele:
gameadm rust start
gameadm rust status
gameadm rust logs
gameadm mc help
Konfiguration: $GAMEADM_DIR/
Module: $MODULES_DIR/
EOF
}
# Spiel-Modul laden
load_game_module() {
local game="$1"
local module_file="$MODULES_DIR/${game}.sh"
if [[ ! -f "$module_file" ]]; then
log "ERROR" "Spiel '$game' nicht gefunden. Verfügbare Module:"
ls -1 "$MODULES_DIR"/*.sh 2>/dev/null | sed 's|.*/||' | sed 's|\.sh$||' | sort || log "WARN" "Keine Module gefunden in $MODULES_DIR"
exit 1
fi
# Modul laden
# shellcheck disable=SC1090
source "$module_file"
}
# Hauptfunktion
main() {
# Verzeichnisse erstellen falls nicht vorhanden
mkdir -p "$GAMEADM_DIR" "$MODULES_DIR"
# Keine Argumente = Hilfe anzeigen
if [[ $# -eq 0 ]]; then
show_help
exit 0
fi
# Erstes Argument ist das Spiel
local game="$1"
shift
# Spezielle Befehle
case "$game" in
"help"|"-h"|"--help")
show_help
exit 0
;;
"list"|"ls")
log "INFO" "Verfügbare Spiele:"
ls -1 "$MODULES_DIR"/*.sh 2>/dev/null | sed 's|.*/||' | sed 's|\.sh$||' | sort || log "WARN" "Keine Module gefunden"
exit 0
;;
"version"|"-v"|"--version")
echo "gameadm v1.0.0 - Modularer Game Server Administrator"
exit 0
;;
esac
# Spiel-Modul laden
load_game_module "$game"
# Modul-spezifische Befehle ausführen
if [[ $# -eq 0 ]]; then
log "ERROR" "Kein Befehl angegeben für '$game'. Verwenden Sie 'gameadm $game help' für Hilfe."
exit 1
fi
local command="$1"
shift
# Befehl an das Modul weiterleiten
if declare -f "cmd_${command}" >/dev/null 2>&1; then
"cmd_${command}" "$@"
else
log "ERROR" "Unbekannter Befehl '$command' für '$game'. Verwenden Sie 'gameadm $game help' für verfügbare Befehle."
exit 1
fi
}
# Hauptprogramm ausführen
main "$@"

146
gameadm/modules/mc.sh Executable file
View File

@ -0,0 +1,146 @@
#!/bin/bash
# Minecraft Server Modul für gameadm
# Beispiel für zukünftige Erweiterungen
# Konfigurationsdatei
CONFIG_FILE="/etc/minecraft-server.conf"
# Konfiguration laden
if [[ -f "$CONFIG_FILE" ]]; then
# shellcheck disable=SC1090
source "$CONFIG_FILE"
else
log "WARN" "Konfig nicht gefunden: $CONFIG_FILE"
fi
# Standardwerte
CONTAINER_NAME=${CONTAINER_NAME:-minecraft-server}
IMAGE=${IMAGE:-docker.io/itzg/minecraft-server:latest}
DATA_DIR=${DATA_DIR:-/srv/minecraft}
PORT=${PORT:-25565}
MEMORY_LIMIT=${MEMORY_LIMIT:-"2g"}
VERSION=${VERSION:-"LATEST"}
EULA=${EULA:-"TRUE"}
# Hilfsfunktionen
ensure_prereqs() {
mkdir -p "$DATA_DIR"
# EULA akzeptieren
if [[ ! -f "$DATA_DIR/eula.txt" ]]; then
echo "eula=$EULA" > "$DATA_DIR/eula.txt"
log "INFO" "EULA akzeptiert: $DATA_DIR/eula.txt"
fi
}
is_running() {
podman inspect -f '{{.State.Running}}' "$CONTAINER_NAME" 2>/dev/null | grep -q true
}
# Befehle
cmd_start() {
ensure_prereqs
if is_running; then
log "INFO" "Bereits gestartet: $CONTAINER_NAME"
exit 0
fi
# Beendeten Container entfernen falls vorhanden
if podman inspect "$CONTAINER_NAME" >/dev/null 2>&1; then
podman rm -f "$CONTAINER_NAME" >/dev/null 2>&1 || true
fi
log "INFO" "Starte $CONTAINER_NAME ..."
podman run -d \
--name "$CONTAINER_NAME" \
--restart=always \
--memory="$MEMORY_LIMIT" \
-p ${PORT}:25565 \
-v "$DATA_DIR:/data" \
-e EULA="$EULA" \
-e VERSION="$VERSION" \
-e MEMORY="$MEMORY_LIMIT" \
"$IMAGE" >/dev/null
log "INFO" "Minecraft Server gestartet."
}
cmd_stop() {
if ! podman inspect "$CONTAINER_NAME" >/dev/null 2>&1; then
log "INFO" "Container existiert nicht: $CONTAINER_NAME"
exit 0
fi
log "INFO" "Stoppe $CONTAINER_NAME ..."
podman stop -t 30 "$CONTAINER_NAME" >/dev/null 2>&1 || true
podman rm "$CONTAINER_NAME" >/dev/null 2>&1 || true
log "INFO" "Minecraft Server gestoppt."
}
cmd_restart() {
cmd_stop || true
cmd_start
}
cmd_status() {
if is_running; then
echo "RUNNING"
podman ps --filter name="^${CONTAINER_NAME}$" --format '{{.Names}}\t{{.Status}}\t{{.Ports}}'
else
if podman inspect "$CONTAINER_NAME" >/dev/null 2>&1; then
echo "EXITED"
else
echo "NOT FOUND"
fi
fi
}
cmd_logs() {
if ! podman inspect "$CONTAINER_NAME" >/dev/null 2>&1; then
log "ERROR" "Container $CONTAINER_NAME existiert nicht"
exit 1
fi
podman logs --tail=200 "$CONTAINER_NAME"
}
cmd_follow() {
if ! podman inspect "$CONTAINER_NAME" >/dev/null 2>&1; then
log "ERROR" "Container $CONTAINER_NAME existiert nicht"
exit 1
fi
podman logs -f "$CONTAINER_NAME"
}
cmd_update() {
log "INFO" "Pull $IMAGE ..."
podman pull "$IMAGE"
log "INFO" "Minecraft Server Image aktualisiert."
}
cmd_help() {
cat <<EOF
Minecraft Server Verwaltung
Verwendung:
gameadm mc <befehl>
Verfügbare Befehle:
start - Startet Minecraft Server
stop - Stoppt Minecraft Server
restart - Startet Server neu
status - Zeigt Server-Status
logs - Zeigt Server-Logs (letzte 200 Zeilen)
follow - Folgt Logs in Echtzeit
update - Aktualisiert Server-Image
help - Zeigt diese Hilfe
Konfiguration: $CONFIG_FILE
Container: $CONTAINER_NAME
Port: $PORT (TCP)
Speicher: $MEMORY_LIMIT
Version: $VERSION
Daten: $DATA_DIR
Hinweis: Dies ist ein Beispiel-Modul für zukünftige Erweiterungen.
EOF
}

154
gameadm/modules/rust.sh Executable file
View File

@ -0,0 +1,154 @@
#!/bin/bash
# Rust Game Server Modul für gameadm
# Ersetzt die Funktionalität von rustadm
# Konfigurationsdatei
CONFIG_FILE="/etc/rust-server.conf"
# Konfiguration laden
if [[ -f "$CONFIG_FILE" ]]; then
# shellcheck disable=SC1090
source "$CONFIG_FILE"
else
log "WARN" "Konfig nicht gefunden: $CONFIG_FILE"
fi
# Standardwerte (können durch Konfig überschrieben werden)
CONTAINER_NAME=${CONTAINER_NAME:-rust-game}
IMAGE=${IMAGE:-docker.io/didstopia/rust-server:latest}
DATA_DIR=${DATA_DIR:-/srv/rust}
PORT=${PORT:-28015}
RCON_PORT=${RCON_PORT:-28016}
MAXPLAYERS=${MAXPLAYERS:-4}
RUST_SERVER_NAME=${RUST_SERVER_NAME:-"PurePowerPh1L's Rust Server"}
SERVER_SECRET_FILE=${SERVER_SECRET_FILE:-/root/secrets/rust_server_password}
RCON_SECRET_FILE=${RCON_SECRET_FILE:-/root/secrets/rust_rcon_password}
EXTRA_ARGS=${EXTRA_ARGS:-"-batchmode -load -nographics +server.secure 1"}
MEMORY_LIMIT=${MEMORY_LIMIT:-""}
# Hilfsfunktionen
ensure_prereqs() {
mkdir -p "$DATA_DIR"
if [[ ! -s "$SERVER_SECRET_FILE" ]]; then
log "ERROR" "Server-Passwortdatei fehlt oder ist leer: $SERVER_SECRET_FILE"
exit 1
fi
if [[ ! -s "$RCON_SECRET_FILE" ]]; then
log "ERROR" "RCON-Passwortdatei fehlt oder ist leer: $RCON_SECRET_FILE"
exit 1
fi
}
is_running() {
podman inspect -f '{{.State.Running}}' "$CONTAINER_NAME" 2>/dev/null | grep -q true
}
# Befehle
cmd_start() {
ensure_prereqs
if is_running; then
log "INFO" "Bereits gestartet: $CONTAINER_NAME"
exit 0
fi
# Beendeten Container entfernen falls vorhanden
if podman inspect "$CONTAINER_NAME" >/dev/null 2>&1; then
podman rm -f "$CONTAINER_NAME" >/dev/null 2>&1 || true
fi
log "INFO" "Starte $CONTAINER_NAME ..."
podman run -d \
--name "$CONTAINER_NAME" \
--restart=always \
${MEMORY_LIMIT:+--memory="$MEMORY_LIMIT"} \
-p ${PORT}:${PORT}/udp \
-p ${PORT}:${PORT}/tcp \
-p ${RCON_PORT}:${RCON_PORT}/tcp \
-v "$DATA_DIR:/steamcmd" \
-e RUST_SERVER_NAME="$RUST_SERVER_NAME" \
-e RUST_SERVER_MAXPLAYERS="$MAXPLAYERS" \
-e RUST_SERVER_PORT="$PORT" \
-e RUST_RCON_PORT="$RCON_PORT" \
-e RUST_RCON_PASSWORD="$(cat "$RCON_SECRET_FILE")" \
-e RUST_SERVER_STARTUP_ARGUMENTS="$EXTRA_ARGS +server.password $(cat "$SERVER_SECRET_FILE")" \
"$IMAGE" >/dev/null
log "INFO" "Rust Server gestartet."
}
cmd_stop() {
if ! podman inspect "$CONTAINER_NAME" >/dev/null 2>&1; then
log "INFO" "Container existiert nicht: $CONTAINER_NAME"
exit 0
fi
log "INFO" "Stoppe $CONTAINER_NAME ..."
podman stop -t 45 "$CONTAINER_NAME" >/dev/null 2>&1 || true
podman rm "$CONTAINER_NAME" >/dev/null 2>&1 || true
log "INFO" "Rust Server gestoppt."
}
cmd_restart() {
cmd_stop || true
cmd_start
}
cmd_status() {
if is_running; then
echo "RUNNING"
podman ps --filter name="^${CONTAINER_NAME}$" --format '{{.Names}}\t{{.Status}}\t{{.Ports}}'
else
if podman inspect "$CONTAINER_NAME" >/dev/null 2>&1; then
echo "EXITED"
else
echo "NOT FOUND"
fi
fi
}
cmd_logs() {
if ! podman inspect "$CONTAINER_NAME" >/dev/null 2>&1; then
log "ERROR" "Container $CONTAINER_NAME existiert nicht"
exit 1
fi
podman logs --tail=200 "$CONTAINER_NAME"
}
cmd_follow() {
if ! podman inspect "$CONTAINER_NAME" >/dev/null 2>&1; then
log "ERROR" "Container $CONTAINER_NAME existiert nicht"
exit 1
fi
podman logs -f "$CONTAINER_NAME"
}
cmd_update() {
log "INFO" "Pull $IMAGE ..."
podman pull "$IMAGE"
log "INFO" "Rust Server Image aktualisiert."
}
cmd_help() {
cat <<EOF
Rust Game Server Verwaltung
Verwendung:
gameadm rust <befehl>
Verfügbare Befehle:
start - Startet Rust Game Server
stop - Stoppt Rust Game Server
restart - Startet Server neu
status - Zeigt Server-Status
logs - Zeigt Server-Logs (letzte 200 Zeilen)
follow - Folgt Logs in Echtzeit
update - Aktualisiert Server-Image
help - Zeigt diese Hilfe
Konfiguration: $CONFIG_FILE
Container: $CONTAINER_NAME
Port: $PORT (UDP/TCP)
RCON: $RCON_PORT (TCP)
Daten: $DATA_DIR
EOF
}