#!/usr/bin/env bash # migrate_superx_webapp.sh # # Migriert eine bestehende SuperX-Installation in eine neue Tomcat-Webapp-Struktur. # # Erwartete Dateien im selben Verzeichnis: # migrate_superx.conf # migrate_superx_webapp.sh # # Modi: # MIGRATION_MODE=full # Webapp wird nach TARGET_WEBAPP kopiert. # db wird nach TARGET_WEBAPP/WEB-INF/conf/edustore/db kopiert oder verschoben. # # MIGRATION_MODE=db_only # Webapp wird nicht kopiert. # db wird in die bestehende oder angegebene Webapp unter WEB-INF/conf/edustore/db kopiert oder verschoben. # # DB_TRANSFER_MODE: # copy: db wird per rsync kopiert. # move: db wird per mv verschoben. Ziel-db darf dabei noch nicht existieren. set -euo pipefail SCRIPT_NAME="$(basename "$0")" SCRIPT_VERSION="1.4" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" CONFIG_FILE="$SCRIPT_DIR/migrate_superx.conf" log() { echo "[$SCRIPT_NAME] $*"; } warn() { echo "[$SCRIPT_NAME] WARNUNG: $*" >&2; } fail() { echo "[$SCRIPT_NAME] FEHLER: $*" >&2; exit 1; } is_true() { case "${1:-false}" in true|TRUE|yes|YES|ja|JA|1) return 0 ;; *) return 1 ;; esac } is_false() { case "${1:-false}" in false|FALSE|no|NO|nein|NEIN|0|"") return 0 ;; *) return 1 ;; esac } is_auto() { case "${1:-}" in auto|AUTO|Auto) return 0 ;; *) return 1 ;; esac } is_root() { [ "$(id -u)" -eq 0 ]; } current_user() { id -un; } user_exists() { id "$1" >/dev/null 2>&1; } group_exists() { getent group "$1" >/dev/null 2>&1; } user_in_group() { local user="$1" local group="$2" id -nG "$user" 2>/dev/null | tr ' ' '\n' | grep -qx "$group" } current_user_matches_target() { [ "$(current_user)" = "$TOMCAT_USER" ] && user_in_group "$(current_user)" "$SUPERX_GROUP" } canon_path() { if command -v realpath >/dev/null 2>&1; then realpath -m "$1" else printf '%s\n' "$1" fi } run() { if is_true "${DRY_RUN:-false}"; then echo "[DRY-RUN] $*" else if is_true "${VERBOSE:-false}"; then echo "+ $*" fi eval "$@" fi } usage() { cat <&2 </dev/null 2>&1 || fail "systemctl nicht gefunden, kann Tomcat nicht stoppen." run "systemctl stop '$TOMCAT_SERVICE'" fi } start_tomcat_if_requested() { if is_true "$START_TOMCAT"; then command -v systemctl >/dev/null 2>&1 || fail "systemctl nicht gefunden, kann Tomcat nicht starten." run "systemctl start '$TOMCAT_SERVICE'" fi } copy_webapp_if_requested() { if [ "$MIGRATION_MODE" != "full" ]; then log "MIGRATION_MODE=db_only: Webapp wird nicht kopiert." return 0 fi command -v rsync >/dev/null 2>&1 || fail "rsync ist nicht installiert oder nicht im PATH." run "mkdir -p '$TARGET_WEBAPP'" RSYNC_DELETE="" if is_true "$DELETE_TARGET"; then RSYNC_DELETE="--delete"; fi log "Kopiere Webapp..." run "rsync -a $RSYNC_DELETE '$SOURCE_WEBAPP/' '$TARGET_WEBAPP/'" } transfer_db() { run "mkdir -p '$TARGET_SUPERX_DIR'" if [ "$DB_TRANSFER_MODE" = "copy" ]; then command -v rsync >/dev/null 2>&1 || fail "rsync ist nicht installiert oder nicht im PATH." RSYNC_DELETE="" if is_true "$DELETE_TARGET"; then RSYNC_DELETE="--delete"; fi log "Kopiere DB-Verzeichnis nach WEB-INF/conf/edustore/db..." run "mkdir -p '$TARGET_DB'" run "rsync -a $RSYNC_DELETE '$SOURCE_DB/' '$TARGET_DB/'" return 0 fi if [ "$DB_TRANSFER_MODE" = "move" ]; then log "Verschiebe DB-Verzeichnis nach WEB-INF/conf/edustore/db..." run "mkdir -p '$(dirname "$TARGET_DB")'" run "mv '$SOURCE_DB' '$TARGET_DB'" return 0 fi fail "Unbekannter DB_TRANSFER_MODE: $DB_TRANSFER_MODE" } backup_target_sql_env() { if [ -f "$TARGET_SQL_ENV" ]; then TS="$(date +%Y%m%d_%H%M%S)" run "cp -p '$TARGET_SQL_ENV' '$TARGET_SQL_ENV.bak.$TS'" else warn "Ziel-SQL_ENV existiert noch nicht: $TARGET_SQL_ENV" fi } update_target_sql_env() { if ! is_true "$UPDATE_SQL_ENV"; then return 0; fi [ -f "$TARGET_SQL_ENV" ] || fail "Ziel-SQL_ENV nicht gefunden: $TARGET_SQL_ENV" backup_target_sql_env if is_true "$DRY_RUN"; then echo "[DRY-RUN] passe SQL_ENV an: $TARGET_SQL_ENV" return 0 fi python3 - "$TARGET_SQL_ENV" "$TARGET_SUPERX_DIR" "$TARGET_WEBAPP" <<'PY' from pathlib import Path import re import sys path = Path(sys.argv[1]) new_superx_dir = sys.argv[2] new_webapp = sys.argv[3] text = path.read_text(encoding="utf-8", errors="surrogateescape").splitlines() out = [] seen_umask = False seen_superx = False seen_webapp = False seen_export_superx = False seen_export_webapp = False for line in text: stripped = line.strip() if re.match(r"^umask\s+", stripped): if not seen_umask: out.append("umask 002") seen_umask = True else: out.append("# " + line) continue if re.match(r"^SUPERX_DIR\s*=", stripped): if not seen_superx: out.append(f'SUPERX_DIR="{new_superx_dir}"') seen_superx = True else: out.append("# " + line) continue if re.match(r"^WEBAPP\s*=", stripped): if not seen_webapp: out.append(f'WEBAPP="{new_webapp}"') seen_webapp = True else: out.append("# " + line) continue if re.match(r"^export\s+SUPERX_DIR\b", stripped): seen_export_superx = True out.append(line) continue if re.match(r"^export\s+WEBAPP\b", stripped): seen_export_webapp = True out.append(line) continue out.append(line) insert = [] if not seen_umask: insert.append("umask 002") if not seen_superx: insert.append(f'SUPERX_DIR="{new_superx_dir}"') if not seen_export_superx: insert.append("export SUPERX_DIR") if not seen_webapp: insert.append(f'WEBAPP="{new_webapp}"') if not seen_export_webapp: insert.append("export WEBAPP") if insert: out = insert + [""] + out path.write_text("\n".join(out) + "\n", encoding="utf-8", errors="surrogateescape") PY } set_rights() { if ! is_true "$SET_RIGHTS"; then log "Rechte setzen ist deaktiviert." return 0 fi [ -d "$TARGET_WEBAPP" ] || fail "TARGET_WEBAPP fehlt: $TARGET_WEBAPP" if is_true "$EFFECTIVE_SET_OWNER"; then log "Setze Owner/Gruppe..." run "chown -R '$TOMCAT_USER:$SUPERX_GROUP' '$TARGET_WEBAPP'" else log "Owner/Gruppe werden nicht gesetzt." fi if is_true "$SET_CHMOD"; then log "Setze Verzeichnisrechte mit setgid-Bit..." run "find '$TARGET_WEBAPP' -type d -exec chmod 2775 {} +" log "Setze Standard-Dateirechte..." run "find '$TARGET_WEBAPP' -type f -exec chmod 664 {} +" log "Setze ausfuehrbare Rechte fuer db/bin..." if [ -d "$TARGET_DB/bin" ]; then run "find '$TARGET_DB/bin' -type f -exec chmod 775 {} +" else warn "db/bin im Ziel nicht gefunden: $TARGET_DB/bin" fi log "Setze ausfuehrbare Rechte fuer *.x und *.sh..." run "find '$TARGET_WEBAPP' -type f \\( -name '*.x' -o -name '*.sh' \\) -exec chmod 775 {} +" else log "chmod ist deaktiviert." fi } final_notes() { cat <