gameadm/install.sh

481 lines
15 KiB
Bash
Executable File

#!/bin/bash
# gameadm Installer - Portable Installation für jedes Linux-System
# Automatische Installation von gameadm mit allen Abhängigkeiten
set -euo pipefail
# 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
# Globale Variablen
GAMEADM_DIR="/etc/gameadm"
MODULES_DIR="$GAMEADM_DIR/modules"
BIN_DIR="/usr/local/bin"
INSTALL_URL_BASE="https://git.pp1l.de/pp1l/gameadm/raw/branch/main"
BACKUP_DIR="/tmp/gameadm-backup-$(date +%Y%m%d-%H%M%S)"
# 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-install]${NC} $message" >&2 ;;
"WARN") echo -e "${YELLOW}[gameadm-install]${NC} $message" >&2 ;;
"ERROR") echo -e "${RED}[gameadm-install]${NC} $message" >&2 ;;
"DEBUG") echo -e "${BLUE}[gameadm-install]${NC} $message" >&2 ;;
*) echo -e "[gameadm-install] $message" >&2 ;;
esac
}
# Prüft ob als root ausgeführt
check_root() {
if [[ $EUID -ne 0 ]]; then
log "ERROR" "Dieses Skript muss als root ausgeführt werden (sudo)."
log "INFO" "Verwenden Sie: sudo $0"
exit 1
fi
}
# Betriebssystem erkennen
detect_os() {
if [[ -f /etc/os-release ]]; then
# shellcheck disable=SC1091
source /etc/os-release
OS_ID="$ID"
OS_VERSION="$VERSION_ID"
log "INFO" "Erkanntes System: $PRETTY_NAME"
else
log "ERROR" "Kann Betriebssystem nicht erkennen (/etc/os-release fehlt)"
exit 1
fi
}
# Paketmanager erkennen und Pakete installieren
install_dependencies() {
log "INFO" "Installiere Abhängigkeiten..."
case "$OS_ID" in
"ubuntu"|"debian")
apt-get update
apt-get install -y podman curl wget git bash coreutils
;;
"fedora"|"centos"|"rhel"|"rocky"|"almalinux")
if command -v dnf >/dev/null 2>&1; then
dnf install -y podman curl wget git bash coreutils
else
yum install -y podman curl wget git bash coreutils
fi
;;
"opensuse"|"opensuse-leap"|"opensuse-tumbleweed")
zypper refresh
zypper install -y podman curl wget git bash coreutils
;;
"arch"|"manjaro")
pacman -Sy --noconfirm podman curl wget git bash coreutils
;;
"alpine")
apk update
apk add podman curl wget git bash coreutils
;;
*)
log "WARN" "Unbekanntes OS: $OS_ID. Versuche manuelle Installation..."
# Versuche mit verfügbaren Paketmanagern
if command -v apt-get >/dev/null 2>&1; then
apt-get update && apt-get install -y podman curl wget git bash coreutils
elif command -v dnf >/dev/null 2>&1; then
dnf install -y podman curl wget git bash coreutils
elif command -v yum >/dev/null 2>&1; then
yum install -y podman curl wget git bash coreutils
elif command -v zypper >/dev/null 2>&1; then
zypper install -y podman curl wget git bash coreutils
elif command -v pacman >/dev/null 2>&1; then
pacman -Sy --noconfirm podman curl wget git bash coreutils
elif command -v apk >/dev/null 2>&1; then
apk add podman curl wget git bash coreutils
else
log "ERROR" "Kein unterstützter Paketmanager gefunden!"
log "ERROR" "Bitte installieren Sie manuell: podman, curl, wget, git, bash, coreutils"
exit 1
fi
;;
esac
log "INFO" "Abhängigkeiten erfolgreich installiert."
}
# Prüft ob alle erforderlichen Tools verfügbar sind
check_dependencies() {
log "INFO" "Prüfe Abhängigkeiten..."
local missing_deps=()
local required_tools=("podman" "curl" "wget" "git" "bash")
for tool in "${required_tools[@]}"; do
if ! command -v "$tool" >/dev/null 2>&1; then
missing_deps+=("$tool")
fi
done
if [[ ${#missing_deps[@]} -gt 0 ]]; then
log "WARN" "Fehlende Abhängigkeiten: ${missing_deps[*]}"
# Standardmäßig vollautomatische Installation
local auto_install=true
# Nur bei expliziter --interactive Flag nachfragen
if [[ "${INTERACTIVE_INSTALL:-}" == "true" ]]; then
# Interaktive Installation nur wenn explizit gewünscht
read -p "Sollen die Abhängigkeiten automatisch installiert werden? (Y/n): " -r
if [[ $REPLY =~ ^[Nn]$ ]]; then
log "ERROR" "Installation abgebrochen. Bitte installieren Sie: ${missing_deps[*]}"
exit 1
fi
fi
log "INFO" "Installiere Abhängigkeiten automatisch..."
install_dependencies
check_dependencies # Rekursiv prüfen nach Installation
else
log "INFO" "Alle Abhängigkeiten sind verfügbar."
fi
}
# Backup erstellen falls gameadm bereits installiert ist
create_backup() {
if [[ -f "$BIN_DIR/gameadm" ]] || [[ -d "$GAMEADM_DIR" ]]; then
log "INFO" "Erstelle Backup der bestehenden Installation..."
mkdir -p "$BACKUP_DIR"
if [[ -f "$BIN_DIR/gameadm" ]]; then
cp "$BIN_DIR/gameadm" "$BACKUP_DIR/"
log "INFO" "Backup: $BIN_DIR/gameadm → $BACKUP_DIR/gameadm"
fi
if [[ -d "$GAMEADM_DIR" ]]; then
cp -r "$GAMEADM_DIR" "$BACKUP_DIR/gameadm-config"
log "INFO" "Backup: $GAMEADM_DIR$BACKUP_DIR/gameadm-config"
fi
log "INFO" "Backup erstellt in: $BACKUP_DIR"
fi
}
# gameadm Dateien herunterladen (falls nicht lokal verfügbar)
download_gameadm() {
local source_dir="."
# Temporäres Verzeichnis für Download
local temp_dir="/tmp/gameadm-download-$$"
mkdir -p "$temp_dir"
cd "$temp_dir"
# Hauptskript herunterladen
mkdir -p bin
if ! curl -fsSL "$INSTALL_URL_BASE/bin/gameadm" -o "bin/gameadm"; then
log "ERROR" "Fehler beim Herunterladen des Hauptskripts"
exit 1
fi
# Module herunterladen
mkdir -p modules
for module in "rust.sh" "mc.sh"; do
if ! curl -fsSL "$INSTALL_URL_BASE/modules/$module" -o "modules/$module"; then
log "WARN" "Fehler beim Herunterladen von Modul: $module"
fi
done
# README herunterladen
if ! curl -fsSL "$INSTALL_URL_BASE/README.md" -o "README.md"; then
log "WARN" "Fehler beim Herunterladen der README.md"
fi
source_dir="$temp_dir"
log "INFO" "Download abgeschlossen."
echo "$source_dir"
}
# gameadm installieren
install_gameadm() {
local source_dir="$1"
log "INFO" "Installiere gameadm..."
# Verzeichnisse erstellen
mkdir -p "$GAMEADM_DIR" "$MODULES_DIR"
# Hauptskript installieren
if [[ -f "$source_dir/bin/gameadm" ]]; then
cp "$source_dir/bin/gameadm" "$BIN_DIR/gameadm"
elif [[ -f "$source_dir/gameadm" ]]; then
cp "$source_dir/gameadm" "$BIN_DIR/gameadm"
else
log "ERROR" "gameadm Hauptskript nicht gefunden in: $source_dir"
log "DEBUG" "Verfügbare Dateien: $(ls -la "$source_dir")"
exit 1
fi
chmod +x "$BIN_DIR/gameadm"
log "INFO" "Hauptskript installiert: $BIN_DIR/gameadm"
# Production Tools installieren (falls vorhanden)
if [[ -f "$source_dir/bin/gameadm-quadlet" ]]; then
cp "$source_dir/bin/gameadm-quadlet" "$BIN_DIR/gameadm-quadlet"
chmod +x "$BIN_DIR/gameadm-quadlet"
log "INFO" "Production Tool installiert: $BIN_DIR/gameadm-quadlet"
fi
# Module installieren
if [[ -d "$source_dir/modules" ]]; then
cp -r "$source_dir/modules/"* "$MODULES_DIR/" 2>/dev/null || true
chmod +x "$MODULES_DIR/"*.sh 2>/dev/null || true
log "INFO" "Module installiert: $MODULES_DIR"
else
log "WARN" "Kein modules Verzeichnis gefunden in: $source_dir"
fi
# README kopieren falls vorhanden
if [[ -f "$source_dir/README.md" ]]; then
cp "$source_dir/README.md" "$GAMEADM_DIR/"
log "INFO" "Dokumentation installiert: $GAMEADM_DIR/README.md"
fi
# Production Files installieren (falls vorhanden)
if [[ -d "$source_dir/production" ]]; then
mkdir -p "$GAMEADM_DIR/production"
cp -r "$source_dir/production/"* "$GAMEADM_DIR/production/" 2>/dev/null || true
chmod +x "$GAMEADM_DIR/production/"*.sh 2>/dev/null || true
log "INFO" "Production Files installiert: $GAMEADM_DIR/production"
fi
}
# Konfigurationsbeispiele erstellen
create_sample_configs() {
log "INFO" "Erstelle Beispiel-Konfigurationen..."
# Rust Server Konfiguration
if [[ ! -f "/etc/rust-server.conf" ]]; then
cat > "/etc/rust-server.conf" <<EOF
# Rust Game Server Konfiguration
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"
SERVER_SECRET_FILE=/root/secrets/rust_server_password
RCON_SECRET_FILE=/root/secrets/rust_rcon_password
EXTRA_ARGS="-batchmode -load -nographics +server.secure 1"
MEMORY_LIMIT=4g
EOF
log "INFO" "Beispiel-Konfiguration erstellt: /etc/rust-server.conf"
fi
# Minecraft Server Konfiguration
if [[ ! -f "/etc/minecraft-server.conf" ]]; then
cat > "/etc/minecraft-server.conf" <<EOF
# Minecraft Server Konfiguration
CONTAINER_NAME=minecraft-server
IMAGE=docker.io/itzg/minecraft-server:latest
DATA_DIR=/srv/minecraft
PORT=25565
MEMORY_LIMIT=2g
VERSION=LATEST
EULA=TRUE
EOF
log "INFO" "Beispiel-Konfiguration erstellt: /etc/minecraft-server.conf"
fi
}
# Podman konfigurieren
configure_podman() {
log "INFO" "Konfiguriere Podman..."
# Podman Socket aktivieren (für Docker-Kompatibilität)
if command -v systemctl >/dev/null 2>&1; then
systemctl enable --now podman.socket 2>/dev/null || true
log "INFO" "Podman Socket aktiviert"
fi
# Registries konfigurieren
local registries_conf="/etc/containers/registries.conf"
if [[ ! -f "$registries_conf" ]]; then
mkdir -p "$(dirname "$registries_conf")"
cat > "$registries_conf" <<EOF
# Podman Registries Konfiguration
[registries.search]
registries = ['docker.io', 'registry.fedoraproject.org', 'quay.io', 'registry.access.redhat.com']
[registries.insecure]
registries = []
[registries.block]
registries = []
EOF
log "INFO" "Podman Registries konfiguriert: $registries_conf"
fi
}
# Installation testen
test_installation() {
log "INFO" "Teste Installation..."
# Prüfe ob gameadm verfügbar ist
if ! command -v gameadm >/dev/null 2>&1; then
log "ERROR" "gameadm nicht im PATH gefunden"
exit 1
fi
# Teste grundlegende Funktionen
if gameadm --version >/dev/null 2>&1; then
log "INFO" "Version-Check erfolgreich"
else
log "ERROR" "gameadm --version fehlgeschlagen"
exit 1
fi
if gameadm list >/dev/null 2>&1; then
log "INFO" "Module-Liste erfolgreich"
else
log "ERROR" "gameadm list fehlgeschlagen"
exit 1
fi
log "INFO" "Installation erfolgreich getestet!"
}
# Installations-Zusammenfassung anzeigen
show_summary() {
log "INFO" "Installation abgeschlossen!"
echo
echo -e "${GREEN}gameadm erfolgreich installiert!${NC}"
echo
echo "Verfügbare Befehle:"
echo " gameadm --help - Hilfe anzeigen"
echo " gameadm list - Verfügbare Spiele auflisten"
echo " gameadm install mc - Minecraft Server installieren/konfigurieren"
echo " gameadm install rust - Rust Server installieren/konfigurieren"
echo " gameadm mc start - Minecraft Server starten"
echo " gameadm rust start - Rust Server starten"
echo
echo "Konfiguration:"
echo " /etc/gameadm/ - Hauptverzeichnis"
echo " /etc/gameadm/modules/ - Spiel-Module"
echo " /etc/rust-server.conf - Rust Server Konfiguration"
echo " /etc/minecraft-server.conf - Minecraft Server Konfiguration"
echo
echo "Nächste Schritte:"
echo "1. Konfigurationsdateien anpassen"
echo "2. Secrets-Dateien erstellen (falls benötigt)"
echo "3. Game Server starten: gameadm <spiel> start"
echo
if [[ -d "$BACKUP_DIR" ]]; then
echo "Backup der alten Installation: $BACKUP_DIR"
echo
fi
}
# Aufräumen nach Installation
cleanup() {
# Temporäre Download-Verzeichnisse löschen
if [[ -n "${temp_dir:-}" && -d "$temp_dir" ]]; then
rm -rf "$temp_dir" 2>/dev/null || true
fi
}
# Signal-Handler für sauberes Aufräumen
trap cleanup EXIT
# Hilfefunktion
show_help() {
echo -e "${BLUE}gameadm Installer${NC}"
echo "Portable Installation für Linux-Systeme"
echo "========================================"
echo
echo "Verwendung: $0 [OPTIONEN]"
echo
echo "Optionen:"
echo " --interactive, -i Interaktive Installation (nachfragen bei Dependencies)"
echo " --help, -h Zeige diese Hilfe"
echo
echo "Umgebungsvariablen:"
echo " INTERACTIVE_INSTALL=true Aktiviert interaktive Installation"
echo
echo "Beispiele:"
echo " $0 # Vollautomatische Installation (Standard)"
echo " $0 --interactive # Nachfragen bei Dependencies"
echo " INTERACTIVE_INSTALL=true $0 # Via Umgebungsvariable"
echo
echo "HINWEIS: Standardmäßig werden alle Dependencies automatisch installiert!"
echo
}
# Hauptfunktion
main() {
# Parameter parsen
while [[ $# -gt 0 ]]; do
case $1 in
--interactive|-i)
export INTERACTIVE_INSTALL=true
shift
;;
--help|-h)
show_help
exit 0
;;
*)
log "ERROR" "Unbekannte Option: $1"
show_help
exit 1
;;
esac
done
echo -e "${BLUE}gameadm Installer${NC}"
echo "Portable Installation für Linux-Systeme"
echo "========================================"
echo
# Voraussetzungen prüfen
check_root
detect_os
# Abhängigkeiten prüfen/installieren
check_dependencies
# Backup erstellen
create_backup
# gameadm herunterladen/vorbereiten
local source_dir="."
if [[ -f "./bin/gameadm" && -d "./modules" ]]; then
log "INFO" "Verwende lokale gameadm Dateien aus aktuellem Verzeichnis"
source_dir="."
else
log "INFO" "Lade gameadm Dateien herunter..."
source_dir=$(download_gameadm)
fi
# Installation durchführen
install_gameadm "$source_dir"
create_sample_configs
configure_podman
# Installation testen
test_installation
# Zusammenfassung anzeigen
show_summary
}
# Skript ausführen
main "$@"