2 changed files with 729 additions and 0 deletions
@ -0,0 +1,89 @@ |
|||||||
|
# migrate_superx.conf |
||||||
|
# Konfiguration fuer die Migration einer bestehenden SuperX-Installation |
||||||
|
# in eine Tomcat-Webapp-Struktur. |
||||||
|
# |
||||||
|
# Beide Dateien muessen im selben Verzeichnis liegen: |
||||||
|
# migrate_superx.conf |
||||||
|
# migrate_superx_webapp.sh |
||||||
|
# |
||||||
|
# Aufruf: |
||||||
|
# ./migrate_superx_webapp.sh |
||||||
|
# |
||||||
|
# Produktiv mit Rechte-/Owner-Anpassung meist: |
||||||
|
# sudo ./migrate_superx_webapp.sh |
||||||
|
# |
||||||
|
# Testlauf: |
||||||
|
# DRY_RUN="true" |
||||||
|
|
||||||
|
# Bestehende SQL_ENV der alten Installation. |
||||||
|
SQL_ENV="/home/superx/db/bin/SQL_ENV" |
||||||
|
|
||||||
|
# Migrationsmodus: |
||||||
|
# full: |
||||||
|
# - kopiert die bestehende Webapp nach TARGET_WEBAPP |
||||||
|
# - kopiert oder verschiebt db nach TARGET_WEBAPP/WEB-INF/conf/edustore/db |
||||||
|
# db_only: |
||||||
|
# - kopiert keine Webapp |
||||||
|
# - verwendet die bestehende WEBAPP aus der SQL_ENV als Ziel, wenn TARGET_WEBAPP="auto" |
||||||
|
# - kopiert oder verschiebt nur db nach WEBAPP/WEB-INF/conf/edustore/db |
||||||
|
MIGRATION_MODE="full" |
||||||
|
|
||||||
|
# Uebertragung des DB-Verzeichnisses: |
||||||
|
# copy: db wird per rsync kopiert, Quelle bleibt erhalten. |
||||||
|
# move: db wird per mv verschoben, Quelle ist danach nicht mehr am alten Ort. |
||||||
|
# Bei move darf TARGET_DB noch nicht existieren. |
||||||
|
DB_TRANSFER_MODE="copy" |
||||||
|
|
||||||
|
# Ziel-Webapp-Verzeichnis. |
||||||
|
# Bei MIGRATION_MODE=full muss hier ein konkreter Pfad stehen. |
||||||
|
# Bei MIGRATION_MODE=db_only kann TARGET_WEBAPP="auto" gesetzt werden. |
||||||
|
TARGET_WEBAPP="/var/lib/tomcat/webapps/superx" |
||||||
|
|
||||||
|
# Benutzer/Gruppe fuer die Zielstruktur. |
||||||
|
TOMCAT_USER="tomcat" |
||||||
|
SUPERX_GROUP="superx" |
||||||
|
|
||||||
|
# Optionaler Tomcat-Service. |
||||||
|
TOMCAT_SERVICE="tomcat10" |
||||||
|
STOP_TOMCAT="false" |
||||||
|
START_TOMCAT="false" |
||||||
|
|
||||||
|
# rsync-Verhalten fuer Webapp-Kopie und DB-Kopie. |
||||||
|
DELETE_TARGET="false" |
||||||
|
|
||||||
|
# Wenn Ziel-Webapp bereits existiert, trotzdem weitermachen? |
||||||
|
ALLOW_EXISTING_TARGET="true" |
||||||
|
|
||||||
|
# Wenn Ziel-DB bereits existiert: |
||||||
|
# Bei DB_TRANSFER_MODE=copy erlaubt true das Ergaenzen/Ueberschreiben per rsync. |
||||||
|
# Bei DB_TRANSFER_MODE=move darf Ziel-DB nie existieren. |
||||||
|
ALLOW_EXISTING_TARGET_DB="true" |
||||||
|
|
||||||
|
# Testlauf ohne Aenderungen. |
||||||
|
DRY_RUN="false" |
||||||
|
|
||||||
|
# Gruppen-/User-Verwaltung. |
||||||
|
ADD_TOMCAT_TO_GROUP="true" |
||||||
|
CREATE_GROUP_IF_MISSING="false" |
||||||
|
|
||||||
|
# SQL_ENV im Ziel anpassen. |
||||||
|
UPDATE_SQL_ENV="true" |
||||||
|
|
||||||
|
# Rechte nach dem Kopieren/Verschieben setzen. |
||||||
|
SET_RIGHTS="true" |
||||||
|
|
||||||
|
# Owner/Gruppe setzen. |
||||||
|
# auto: root setzt chown; gleicher User mit passender Gruppe ueberspringt chown; sonst Abbruch. |
||||||
|
# true: chown immer versuchen. |
||||||
|
# false: chown nie ausfuehren. |
||||||
|
SET_OWNER="auto" |
||||||
|
|
||||||
|
# chmod setzen. |
||||||
|
SET_CHMOD="true" |
||||||
|
|
||||||
|
# Sicherheitspruefung fuer bereits migrierte Struktur. |
||||||
|
# Nur im Notfall auf true setzen. |
||||||
|
FORCE_ALREADY_MIGRATED="false" |
||||||
|
|
||||||
|
# Optional: zusaetzliche Ausgabe. |
||||||
|
VERBOSE="true" |
||||||
@ -0,0 +1,640 @@ |
|||||||
|
#!/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 <<USAGE |
||||||
|
Nutzung: |
||||||
|
./$SCRIPT_NAME |
||||||
|
|
||||||
|
Hinweis: |
||||||
|
Die Datei migrate_superx.conf muss im selben Verzeichnis liegen wie dieses Skript. |
||||||
|
|
||||||
|
Migrationsmodi: |
||||||
|
MIGRATION_MODE=full |
||||||
|
MIGRATION_MODE=db_only |
||||||
|
|
||||||
|
DB-Uebertragung: |
||||||
|
DB_TRANSFER_MODE=copy |
||||||
|
DB_TRANSFER_MODE=move |
||||||
|
USAGE |
||||||
|
} |
||||||
|
|
||||||
|
load_config() { |
||||||
|
[ -f "$CONFIG_FILE" ] || { usage; fail "Config-Datei nicht gefunden: $CONFIG_FILE"; } |
||||||
|
|
||||||
|
# shellcheck disable=SC1090 |
||||||
|
. "$CONFIG_FILE" |
||||||
|
|
||||||
|
: "${SQL_ENV:?SQL_ENV ist nicht gesetzt}" |
||||||
|
: "${TARGET_WEBAPP:?TARGET_WEBAPP ist nicht gesetzt}" |
||||||
|
: "${TOMCAT_USER:?TOMCAT_USER ist nicht gesetzt}" |
||||||
|
: "${SUPERX_GROUP:?SUPERX_GROUP ist nicht gesetzt}" |
||||||
|
|
||||||
|
MIGRATION_MODE="${MIGRATION_MODE:-full}" |
||||||
|
DB_TRANSFER_MODE="${DB_TRANSFER_MODE:-copy}" |
||||||
|
STOP_TOMCAT="${STOP_TOMCAT:-false}" |
||||||
|
START_TOMCAT="${START_TOMCAT:-false}" |
||||||
|
TOMCAT_SERVICE="${TOMCAT_SERVICE:-tomcat10}" |
||||||
|
DELETE_TARGET="${DELETE_TARGET:-false}" |
||||||
|
ALLOW_EXISTING_TARGET="${ALLOW_EXISTING_TARGET:-true}" |
||||||
|
ALLOW_EXISTING_TARGET_DB="${ALLOW_EXISTING_TARGET_DB:-true}" |
||||||
|
DRY_RUN="${DRY_RUN:-false}" |
||||||
|
ADD_TOMCAT_TO_GROUP="${ADD_TOMCAT_TO_GROUP:-true}" |
||||||
|
CREATE_GROUP_IF_MISSING="${CREATE_GROUP_IF_MISSING:-false}" |
||||||
|
UPDATE_SQL_ENV="${UPDATE_SQL_ENV:-true}" |
||||||
|
SET_RIGHTS="${SET_RIGHTS:-true}" |
||||||
|
SET_OWNER="${SET_OWNER:-auto}" |
||||||
|
SET_CHMOD="${SET_CHMOD:-true}" |
||||||
|
FORCE_ALREADY_MIGRATED="${FORCE_ALREADY_MIGRATED:-false}" |
||||||
|
VERBOSE="${VERBOSE:-true}" |
||||||
|
|
||||||
|
case "$MIGRATION_MODE" in full|db_only) ;; *) fail "Ungueltiger Wert fuer MIGRATION_MODE: $MIGRATION_MODE. Erlaubt: full, db_only." ;; esac |
||||||
|
case "$DB_TRANSFER_MODE" in copy|move) ;; *) fail "Ungueltiger Wert fuer DB_TRANSFER_MODE: $DB_TRANSFER_MODE. Erlaubt: copy, move." ;; esac |
||||||
|
case "$SET_OWNER" in auto|AUTO|Auto|true|TRUE|yes|YES|ja|JA|1|false|FALSE|no|NO|nein|NEIN|0) ;; *) fail "Ungueltiger Wert fuer SET_OWNER: $SET_OWNER. Erlaubt: auto, true, false." ;; esac |
||||||
|
} |
||||||
|
|
||||||
|
validate_basic_paths() { |
||||||
|
[ -f "$SQL_ENV" ] || fail "SQL_ENV nicht gefunden: $SQL_ENV" |
||||||
|
|
||||||
|
if [ "$MIGRATION_MODE" = "full" ]; then |
||||||
|
[ "$TARGET_WEBAPP" != "auto" ] || fail "TARGET_WEBAPP=auto ist bei MIGRATION_MODE=full nicht erlaubt." |
||||||
|
fi |
||||||
|
|
||||||
|
if [ "$TARGET_WEBAPP" != "auto" ]; then |
||||||
|
case "$TARGET_WEBAPP" in |
||||||
|
""|"/"|"/var"|"/var/lib"|"/var/lib/tomcat"|"/var/lib/tomcat/webapps"|"/srv"|"/srv/tomcat"|"/srv/tomcat/webapps"|"/home"|"/tmp") |
||||||
|
fail "TARGET_WEBAPP ist zu allgemein/gefaehrlich: $TARGET_WEBAPP" |
||||||
|
;; |
||||||
|
esac |
||||||
|
fi |
||||||
|
} |
||||||
|
|
||||||
|
check_source_not_already_migrated() { |
||||||
|
local superx_real webapp_real |
||||||
|
superx_real="$(canon_path "$SOURCE_SUPERX_DIR")" |
||||||
|
webapp_real="$(canon_path "$SOURCE_WEBAPP")" |
||||||
|
|
||||||
|
SOURCE_SUPERX_DIR_REAL="$superx_real" |
||||||
|
SOURCE_WEBAPP_REAL="$webapp_real" |
||||||
|
|
||||||
|
case "$superx_real" in |
||||||
|
"$webapp_real"/*) |
||||||
|
if is_true "$FORCE_ALREADY_MIGRATED"; then |
||||||
|
warn "SUPERX_DIR liegt bereits innerhalb von WEBAPP. FORCE_ALREADY_MIGRATED=true ist gesetzt, Migration wird trotzdem fortgesetzt." |
||||||
|
else |
||||||
|
fail "SUPERX_DIR liegt bereits innerhalb von WEBAPP. Die Installation sieht bereits nach der neuen Webapp-Struktur aus. |
||||||
|
|
||||||
|
SUPERX_DIR=$SOURCE_SUPERX_DIR |
||||||
|
WEBAPP=$SOURCE_WEBAPP |
||||||
|
|
||||||
|
Realpfade: |
||||||
|
SUPERX_DIR=$superx_real |
||||||
|
WEBAPP=$webapp_real |
||||||
|
|
||||||
|
Migration wird abgebrochen. |
||||||
|
|
||||||
|
Nur wenn du die Risiken kennst und trotzdem migrieren willst: |
||||||
|
FORCE_ALREADY_MIGRATED=\"true\"" |
||||||
|
fi |
||||||
|
;; |
||||||
|
esac |
||||||
|
} |
||||||
|
|
||||||
|
load_old_sql_env() { |
||||||
|
# shellcheck disable=SC1090 |
||||||
|
. "$SQL_ENV" |
||||||
|
|
||||||
|
[ -n "${SUPERX_DIR:-}" ] || fail "SUPERX_DIR wurde durch SQL_ENV nicht gesetzt." |
||||||
|
[ -n "${WEBAPP:-}" ] || fail "WEBAPP wurde durch SQL_ENV nicht gesetzt." |
||||||
|
|
||||||
|
SOURCE_SUPERX_DIR="$SUPERX_DIR" |
||||||
|
SOURCE_WEBAPP="$WEBAPP" |
||||||
|
|
||||||
|
check_source_not_already_migrated |
||||||
|
|
||||||
|
if [ -d "$SOURCE_SUPERX_DIR/db/bin" ]; then |
||||||
|
SOURCE_DB="$SOURCE_SUPERX_DIR/db" |
||||||
|
SOURCE_TYPE="ALT_ODER_FULL_RELEASE" |
||||||
|
elif [ -d "$SOURCE_SUPERX_DIR/bin" ] && [ "$(basename "$SOURCE_SUPERX_DIR")" = "db" ]; then |
||||||
|
SOURCE_DB="$SOURCE_SUPERX_DIR" |
||||||
|
SOURCE_TYPE="DB_DIREKT" |
||||||
|
elif [ -d "$SOURCE_SUPERX_DIR/db" ]; then |
||||||
|
SOURCE_DB="$SOURCE_SUPERX_DIR/db" |
||||||
|
SOURCE_TYPE="ALT_ODER_FULL_RELEASE" |
||||||
|
else |
||||||
|
fail "DB-Verzeichnis konnte nicht erkannt werden. Erwartet: \$SUPERX_DIR/db/bin oder \$SUPERX_DIR/bin. SUPERX_DIR=$SOURCE_SUPERX_DIR" |
||||||
|
fi |
||||||
|
|
||||||
|
[ -d "$SOURCE_WEBAPP/WEB-INF" ] || fail "WEBAPP scheint keine SuperX-Webapp zu sein: $SOURCE_WEBAPP/WEB-INF fehlt." |
||||||
|
[ -d "$SOURCE_DB/bin" ] || fail "DB-bin-Verzeichnis fehlt: $SOURCE_DB/bin" |
||||||
|
[ -f "$SOURCE_DB/bin/SQL_ENV" ] || warn "Quelle enthaelt keine SQL_ENV unter: $SOURCE_DB/bin/SQL_ENV" |
||||||
|
|
||||||
|
if [ "$MIGRATION_MODE" = "db_only" ] && [ "$TARGET_WEBAPP" = "auto" ]; then |
||||||
|
TARGET_WEBAPP="$SOURCE_WEBAPP" |
||||||
|
fi |
||||||
|
|
||||||
|
TARGET_SUPERX_DIR="$TARGET_WEBAPP/WEB-INF/conf/edustore" |
||||||
|
TARGET_DB="$TARGET_SUPERX_DIR/db" |
||||||
|
TARGET_SQL_ENV="$TARGET_DB/bin/SQL_ENV" |
||||||
|
|
||||||
|
SOURCE_DB_REAL="$(canon_path "$SOURCE_DB")" |
||||||
|
TARGET_DB_REAL="$(canon_path "$TARGET_DB")" |
||||||
|
TARGET_WEBAPP_REAL="$(canon_path "$TARGET_WEBAPP")" |
||||||
|
} |
||||||
|
|
||||||
|
normalize_owner_mode() { |
||||||
|
EFFECTIVE_SET_OWNER="$SET_OWNER" |
||||||
|
|
||||||
|
if ! is_true "$SET_RIGHTS"; then EFFECTIVE_SET_OWNER="false"; return 0; fi |
||||||
|
if is_false "$SET_OWNER"; then EFFECTIVE_SET_OWNER="false"; return 0; fi |
||||||
|
|
||||||
|
if is_auto "$SET_OWNER"; then |
||||||
|
if is_root; then EFFECTIVE_SET_OWNER="true"; return 0; fi |
||||||
|
if current_user_matches_target; then |
||||||
|
EFFECTIVE_SET_OWNER="false" |
||||||
|
log "SET_OWNER=auto: chown wird uebersprungen, weil laufender User '$TOMCAT_USER' ist und zur Gruppe '$SUPERX_GROUP' gehoert." |
||||||
|
return 0 |
||||||
|
fi |
||||||
|
EFFECTIVE_SET_OWNER="true" |
||||||
|
return 0 |
||||||
|
fi |
||||||
|
|
||||||
|
if is_true "$SET_OWNER"; then EFFECTIVE_SET_OWNER="true"; return 0; fi |
||||||
|
} |
||||||
|
|
||||||
|
root_needed_reasons() { |
||||||
|
local reasons=() |
||||||
|
|
||||||
|
if is_true "$STOP_TOMCAT"; then reasons+=("STOP_TOMCAT=true"); fi |
||||||
|
if is_true "$START_TOMCAT"; then reasons+=("START_TOMCAT=true"); fi |
||||||
|
if is_true "$CREATE_GROUP_IF_MISSING" && ! group_exists "$SUPERX_GROUP"; then reasons+=("CREATE_GROUP_IF_MISSING=true und Gruppe '$SUPERX_GROUP' fehlt"); fi |
||||||
|
|
||||||
|
if is_true "$ADD_TOMCAT_TO_GROUP"; then |
||||||
|
if user_exists "$TOMCAT_USER" && group_exists "$SUPERX_GROUP"; then |
||||||
|
if ! user_in_group "$TOMCAT_USER" "$SUPERX_GROUP"; then |
||||||
|
reasons+=("ADD_TOMCAT_TO_GROUP=true und '$TOMCAT_USER' ist noch nicht in Gruppe '$SUPERX_GROUP'") |
||||||
|
fi |
||||||
|
fi |
||||||
|
fi |
||||||
|
|
||||||
|
if is_true "$SET_RIGHTS" && is_true "$EFFECTIVE_SET_OWNER"; then reasons+=("chown auf '$TOMCAT_USER:$SUPERX_GROUP'"); fi |
||||||
|
|
||||||
|
if [ "${#reasons[@]}" -gt 0 ]; then printf '%s\n' "${reasons[@]}"; return 0; fi |
||||||
|
return 1 |
||||||
|
} |
||||||
|
|
||||||
|
validate_privileges() { |
||||||
|
normalize_owner_mode |
||||||
|
if is_root; then return 0; fi |
||||||
|
|
||||||
|
local reasons |
||||||
|
if reasons="$(root_needed_reasons)"; then |
||||||
|
cat >&2 <<ROOTERR |
||||||
|
[$SCRIPT_NAME] FEHLER: Dieses Skript laeuft nicht als root, aber folgende Aktionen brauchen root-Rechte: |
||||||
|
|
||||||
|
$reasons |
||||||
|
|
||||||
|
Moeglichkeiten: |
||||||
|
|
||||||
|
1. Produktiv als root ausfuehren: |
||||||
|
sudo ./$SCRIPT_NAME |
||||||
|
|
||||||
|
2. Test ohne root, wenn alles dem laufenden User gehoeren soll: |
||||||
|
TOMCAT_USER="$(current_user)" |
||||||
|
SUPERX_GROUP="<passende Gruppe>" |
||||||
|
ADD_TOMCAT_TO_GROUP="false" |
||||||
|
STOP_TOMCAT="false" |
||||||
|
START_TOMCAT="false" |
||||||
|
SET_OWNER="auto" |
||||||
|
|
||||||
|
3. Rechte komplett ueberspringen: |
||||||
|
SET_RIGHTS="false" |
||||||
|
ROOTERR |
||||||
|
exit 1 |
||||||
|
fi |
||||||
|
} |
||||||
|
|
||||||
|
print_summary() { |
||||||
|
cat <<SUMMARY |
||||||
|
|
||||||
|
=== SuperX Migration Tool $SCRIPT_VERSION === |
||||||
|
|
||||||
|
Config: |
||||||
|
CONFIG_FILE = $CONFIG_FILE |
||||||
|
DRY_RUN = ${DRY_RUN:-false} |
||||||
|
RUNNING_AS = $(current_user) |
||||||
|
IS_ROOT = $(is_root && echo true || echo false) |
||||||
|
|
||||||
|
Modus: |
||||||
|
MIGRATION_MODE = $MIGRATION_MODE |
||||||
|
DB_TRANSFER_MODE = $DB_TRANSFER_MODE |
||||||
|
|
||||||
|
Quelle: |
||||||
|
SQL_ENV = $SQL_ENV |
||||||
|
SOURCE_TYPE = $SOURCE_TYPE |
||||||
|
SOURCE_SUPERX_DIR = $SOURCE_SUPERX_DIR |
||||||
|
SOURCE_WEBAPP = $SOURCE_WEBAPP |
||||||
|
SOURCE_DB = $SOURCE_DB |
||||||
|
SOURCE_SUPERX_DIR_REAL = ${SOURCE_SUPERX_DIR_REAL:-} |
||||||
|
SOURCE_WEBAPP_REAL = ${SOURCE_WEBAPP_REAL:-} |
||||||
|
SOURCE_DB_REAL = ${SOURCE_DB_REAL:-} |
||||||
|
|
||||||
|
Ziel: |
||||||
|
TARGET_WEBAPP = $TARGET_WEBAPP |
||||||
|
TARGET_WEBAPP_REAL = ${TARGET_WEBAPP_REAL:-} |
||||||
|
TARGET_SUPERX_DIR = $TARGET_SUPERX_DIR |
||||||
|
TARGET_DB = $TARGET_DB |
||||||
|
TARGET_DB_REAL = ${TARGET_DB_REAL:-} |
||||||
|
TARGET_SQL_ENV = $TARGET_SQL_ENV |
||||||
|
|
||||||
|
Rechte: |
||||||
|
TOMCAT_USER = $TOMCAT_USER |
||||||
|
SUPERX_GROUP = $SUPERX_GROUP |
||||||
|
SET_RIGHTS = $SET_RIGHTS |
||||||
|
SET_OWNER = $SET_OWNER |
||||||
|
EFFECTIVE_SET_OWNER = $EFFECTIVE_SET_OWNER |
||||||
|
SET_CHMOD = $SET_CHMOD |
||||||
|
|
||||||
|
Optionen: |
||||||
|
STOP_TOMCAT = $STOP_TOMCAT |
||||||
|
START_TOMCAT = $START_TOMCAT |
||||||
|
TOMCAT_SERVICE = $TOMCAT_SERVICE |
||||||
|
DELETE_TARGET = $DELETE_TARGET |
||||||
|
ALLOW_EXISTING_TARGET = $ALLOW_EXISTING_TARGET |
||||||
|
ALLOW_EXISTING_TARGET_DB = $ALLOW_EXISTING_TARGET_DB |
||||||
|
UPDATE_SQL_ENV = $UPDATE_SQL_ENV |
||||||
|
FORCE_ALREADY_MIGRATED = $FORCE_ALREADY_MIGRATED |
||||||
|
|
||||||
|
======================================== |
||||||
|
|
||||||
|
SUMMARY |
||||||
|
} |
||||||
|
|
||||||
|
validate_users_and_groups() { |
||||||
|
user_exists "$TOMCAT_USER" || fail "Tomcat-User existiert nicht: $TOMCAT_USER" |
||||||
|
|
||||||
|
if ! group_exists "$SUPERX_GROUP"; then |
||||||
|
if is_true "$CREATE_GROUP_IF_MISSING"; then run "groupadd '$SUPERX_GROUP'"; else fail "Gruppe existiert nicht: $SUPERX_GROUP. Entweder Gruppe anlegen oder CREATE_GROUP_IF_MISSING=true setzen."; fi |
||||||
|
fi |
||||||
|
|
||||||
|
if is_true "$ADD_TOMCAT_TO_GROUP"; then |
||||||
|
if user_in_group "$TOMCAT_USER" "$SUPERX_GROUP"; then |
||||||
|
log "Tomcat-User '$TOMCAT_USER' ist bereits Mitglied der Gruppe '$SUPERX_GROUP'." |
||||||
|
else |
||||||
|
run "usermod -aG '$SUPERX_GROUP' '$TOMCAT_USER'" |
||||||
|
warn "Der Tomcat-Dienst muss neu gestartet werden, damit die neue Gruppenmitgliedschaft aktiv wird." |
||||||
|
fi |
||||||
|
fi |
||||||
|
} |
||||||
|
|
||||||
|
validate_target() { |
||||||
|
if [ "$TARGET_WEBAPP" = "$SOURCE_WEBAPP" ] && [ "$MIGRATION_MODE" = "full" ]; then |
||||||
|
fail "TARGET_WEBAPP darf bei MIGRATION_MODE=full nicht identisch mit SOURCE_WEBAPP sein." |
||||||
|
fi |
||||||
|
|
||||||
|
if [ -e "$TARGET_WEBAPP" ] && [ ! -d "$TARGET_WEBAPP" ]; then |
||||||
|
fail "TARGET_WEBAPP existiert, ist aber kein Verzeichnis: $TARGET_WEBAPP" |
||||||
|
fi |
||||||
|
|
||||||
|
if [ "$MIGRATION_MODE" = "full" ] && [ -d "$TARGET_WEBAPP/WEB-INF" ] && ! is_true "$ALLOW_EXISTING_TARGET"; then |
||||||
|
fail "Ziel-Webapp existiert bereits: $TARGET_WEBAPP. Setze ALLOW_EXISTING_TARGET=true, wenn ergaenzt werden darf." |
||||||
|
fi |
||||||
|
|
||||||
|
if [ "$SOURCE_DB_REAL" = "$TARGET_DB_REAL" ]; then |
||||||
|
fail "SOURCE_DB und TARGET_DB sind identisch. Migration wird abgebrochen.\n\nSOURCE_DB=$SOURCE_DB\nTARGET_DB=$TARGET_DB" |
||||||
|
fi |
||||||
|
|
||||||
|
case "$TARGET_DB_REAL" in |
||||||
|
"$SOURCE_DB_REAL"/*) |
||||||
|
fail "TARGET_DB liegt innerhalb von SOURCE_DB. Das wuerde zu einer Verschachtelung fuehren.\n\nSOURCE_DB=$SOURCE_DB\nTARGET_DB=$TARGET_DB" |
||||||
|
;; |
||||||
|
esac |
||||||
|
|
||||||
|
case "$SOURCE_DB_REAL" in |
||||||
|
"$TARGET_DB_REAL"/*) |
||||||
|
fail "SOURCE_DB liegt innerhalb von TARGET_DB. Das wuerde zu einer Verschachtelung fuehren.\n\nSOURCE_DB=$SOURCE_DB\nTARGET_DB=$TARGET_DB" |
||||||
|
;; |
||||||
|
esac |
||||||
|
|
||||||
|
if [ "$DB_TRANSFER_MODE" = "move" ] && [ -e "$TARGET_DB" ]; then |
||||||
|
fail "DB_TRANSFER_MODE=move ist gesetzt, aber TARGET_DB existiert bereits.\n\nTARGET_DB=$TARGET_DB\n\nBei move wird nicht in ein bestehendes Zielverzeichnis verschoben, um Verschachtelungen wie db/db zu vermeiden." |
||||||
|
fi |
||||||
|
|
||||||
|
if [ "$DB_TRANSFER_MODE" = "copy" ] && [ -e "$TARGET_DB" ] && ! is_true "$ALLOW_EXISTING_TARGET_DB"; then |
||||||
|
fail "TARGET_DB existiert bereits: $TARGET_DB. Setze ALLOW_EXISTING_TARGET_DB=true, wenn per rsync ergaenzt werden darf." |
||||||
|
fi |
||||||
|
} |
||||||
|
|
||||||
|
stop_tomcat_if_requested() { |
||||||
|
if is_true "$STOP_TOMCAT"; then |
||||||
|
command -v systemctl >/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 <<EOFNOTE |
||||||
|
|
||||||
|
Migration abgeschlossen. |
||||||
|
|
||||||
|
Naechste sinnvolle Pruefungen: |
||||||
|
|
||||||
|
ls -ld "$TARGET_WEBAPP" |
||||||
|
ls -ld "$TARGET_DB" |
||||||
|
ls -l "$TARGET_DB/bin/SQL_ENV" |
||||||
|
|
||||||
|
Neue SQL_ENV laden: |
||||||
|
|
||||||
|
. "$TARGET_SQL_ENV" |
||||||
|
|
||||||
|
Pruefen: |
||||||
|
|
||||||
|
echo \$SUPERX_DIR |
||||||
|
echo \$WEBAPP |
||||||
|
umask |
||||||
|
|
||||||
|
Hinweis: |
||||||
|
Falls der Tomcat-User neu zur Gruppe '$SUPERX_GROUP' hinzugefuegt wurde, |
||||||
|
muss Tomcat neu gestartet werden, damit die Gruppenrechte greifen. |
||||||
|
|
||||||
|
EOFNOTE |
||||||
|
|
||||||
|
if [ "$DB_TRANSFER_MODE" = "move" ]; then |
||||||
|
warn "DB_TRANSFER_MODE=move wurde verwendet. Das alte DB-Verzeichnis wurde verschoben und liegt nicht mehr unter: $SOURCE_DB" |
||||||
|
fi |
||||||
|
} |
||||||
|
|
||||||
|
main() { |
||||||
|
load_config |
||||||
|
validate_basic_paths |
||||||
|
load_old_sql_env |
||||||
|
validate_privileges |
||||||
|
print_summary |
||||||
|
validate_users_and_groups |
||||||
|
validate_target |
||||||
|
stop_tomcat_if_requested |
||||||
|
copy_webapp_if_requested |
||||||
|
transfer_db |
||||||
|
update_target_sql_env |
||||||
|
set_rights |
||||||
|
start_tomcat_if_requested |
||||||
|
final_notes |
||||||
|
} |
||||||
|
|
||||||
|
main "$@" |
||||||
Loading…
Reference in new issue