#!/usr/bin/env bash # migrate_superx_webapp.sh # Version 1.5 # # Migriert eine bestehende SuperX-Installation in eine neue Webapp-Struktur. # Standardziel: /home/superx/webapps/superx # Optional: Symlink aus Tomcat-webapps auf TARGET_WEBAPP. set -euo pipefail SCRIPT_NAME="$(basename "$0")" SCRIPT_VERSION="1.6" 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() { id -nG "$1" 2>/dev/null | tr ' ' '\n' | grep -qx "$2"; } current_user_matches_target() { [ "$(current_user)" = "$WEBAPP_USER" ] && user_in_group "$(current_user)" "$WEBAPP_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 </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() { [ "$MIGRATION_MODE" != "full" ] && { log "MIGRATION_MODE=db_only: Webapp wird nicht kopiert."; return 0; } command -v rsync >/dev/null 2>&1 || fail "rsync ist nicht installiert oder nicht im PATH." run "mkdir -p '$TARGET_WEBAPP'" RSYNC_DELETE=""; is_true "$DELETE_TARGET" && RSYNC_DELETE="--delete" 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=""; is_true "$DELETE_TARGET" && RSYNC_DELETE="--delete" log "Kopiere DB-Verzeichnis nach WEB-INF/conf/edustore/db..." run "mkdir -p '$TARGET_DB'" run "rsync -a $RSYNC_DELETE '$SOURCE_DB/' '$TARGET_DB/'" else log "Verschiebe DB-Verzeichnis nach WEB-INF/conf/edustore/db..." run "mkdir -p '$(dirname "$TARGET_DB")'" run "mv '$SOURCE_DB' '$TARGET_DB'" fi } 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() { is_true "$UPDATE_SQL_ENV" || return 0 [ -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, sys path = Path(sys.argv[1]); new_superx_dir = sys.argv[2]; new_webapp = sys.argv[3] lines = path.read_text(encoding='utf-8', errors='surrogateescape').splitlines() out=[]; seen_umask=seen_superx=seen_webapp=seen_export_superx=seen_export_webapp=False for line in lines: s=line.strip() if re.match(r'^umask\s+', s): if not seen_umask: out.append('umask 002'); seen_umask=True else: out.append('# '+line) elif re.match(r'^SUPERX_DIR\s*=', s): if not seen_superx: out.append(f'SUPERX_DIR="{new_superx_dir}"'); seen_superx=True else: out.append('# '+line) elif re.match(r'^WEBAPP\s*=', s): if not seen_webapp: out.append(f'WEBAPP="{new_webapp}"'); seen_webapp=True else: out.append('# '+line) elif re.match(r'^export\s+SUPERX_DIR\b', s): seen_export_superx=True; out.append(line) elif re.match(r'^export\s+WEBAPP\b', s): seen_export_webapp=True; out.append(line) else: 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" log "Setze Rechte fuer Ziel-Webapp und Elternverzeichnis..." if is_true "$EFFECTIVE_SET_OWNER"; then log "Setze Owner/Gruppe rekursiv fuer TARGET_WEBAPP..." run "chown -R '$WEBAPP_USER:$WEBAPP_GROUP' '$TARGET_WEBAPP'" if [ -d "$TARGET_WEBAPP_PARENT" ]; then log "Setze Owner/Gruppe fuer TARGET_WEBAPP_PARENT..." run "chown '$WEBAPP_USER:$WEBAPP_GROUP' '$TARGET_WEBAPP_PARENT'" fi else log "Owner wird nicht gesetzt." if is_true "$EFFECTIVE_SET_GROUP"; then log "Setze Gruppe rekursiv per chgrp fuer TARGET_WEBAPP..." run "chgrp -R '$WEBAPP_GROUP' '$TARGET_WEBAPP'" if [ -d "$TARGET_WEBAPP_PARENT" ]; then log "Setze Gruppe fuer TARGET_WEBAPP_PARENT..." run "chgrp '$WEBAPP_GROUP' '$TARGET_WEBAPP_PARENT'" fi fi fi if is_true "$SET_CHMOD"; then log "Setze Rechte fuer TARGET_WEBAPP_PARENT..." if [ -d "$TARGET_WEBAPP_PARENT" ]; then run "chmod 2775 '$TARGET_WEBAPP_PARENT'" fi 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 } create_tomcat_symlink_if_requested() { is_true "$CREATE_TOMCAT_SYMLINK" || { log "Tomcat-Symlink wird nicht erstellt."; return 0; } log "Erstelle Tomcat-Symlink..." run "mkdir -p '$TOMCAT_WEBAPPS_DIR'" [ -L "$TOMCAT_SYMLINK_PATH" ] && is_true "$REPLACE_EXISTING_SYMLINK" && run "rm '$TOMCAT_SYMLINK_PATH'" run "ln -s '$TARGET_WEBAPP' '$TOMCAT_SYMLINK_PATH'" } final_notes() { cat <