commit 12589ff2525bb0b282cc8aedb66d9f5e2a69bec7 Author: Automation Admin Date: Thu Aug 14 21:20:25 2025 +0000 Initial commit: gameadm - Modulares Game Server Administration System - Modulares Design für verschiedene Game Server - Ersetzt rustadm mit erweiterbarer Architektur - Vollständig funktionales Rust Server Modul - Minecraft Server Modul als Beispiel für Erweiterungen - Zentrale Verwaltung durch /usr/local/bin/gameadm - Farbige Ausgabe und robuste Fehlerbehandlung - Umfassende Dokumentation mit Migrations- und Entwicklungshinweisen Struktur: - bin/gameadm - Hauptskript für zentrale Verwaltung - modules/*.sh - Spiel-spezifische Module - README.md - Vollständige Dokumentation Verwendung: gameadm [optionen] Beispiel: gameadm rust start diff --git a/README.md b/README.md new file mode 100644 index 0000000..0a0cdd3 --- /dev/null +++ b/README.md @@ -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 [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 < [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 "$@" diff --git a/modules/mc.sh b/modules/mc.sh new file mode 100755 index 0000000..4e84f13 --- /dev/null +++ b/modules/mc.sh @@ -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 < + +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 +} diff --git a/modules/rust.sh b/modules/rust.sh new file mode 100755 index 0000000..f5d4215 --- /dev/null +++ b/modules/rust.sh @@ -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 < + +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 +}