#!/bin/bash # $0 [--decrypt ] [openslx] [dozmod] TMDIR="/opt/taskmanager" BACKUP="$1" if [ -z "$BACKUP" ] || [ ! -f "$BACKUP" ]; then echo "Backup file not found: $BACKUP" exit 1 fi shift RES_OPENSLX=0 RES_SAT=0 decrypt= mode= while [ $# -gt 0 ]; do case "$1" in openslx) RES_OPENSLX=1 echo "Restoring system config" ;; dozmod) RES_SAT=1 echo "Restoring VM and lecture db" ;; --decrypt) decrypt="$2" echo "Expecting AES encrypted archive" shift ;; --restore) mode="restore" ;; --test) mode="test" ;; *) echo "Error: Restore mode params must be one of openslx, dozmod (Got $1)" exit 1 ;; esac shift done decryptor() { if ! openssl enc -d -aes-256-cbc -pbkdf2 -pass "env:$decrypt" -in "$1" -out "$2" \ && ! openssl enc -d -aes-256-cbc -pass "env:$decrypt" -in "$1" -out "$2"; then echo "- - - - - - - - - - - - - - - - -" echo "- Could not decrypt backup" echo "- Wrong password?" echo "- - - - - - - - - - - - - - - - -" rm -f -- "$2" exit 1 fi } if [ -z "$mode" ]; then echo "No mode given" exit 1 elif [ "$mode" = "test" ]; then # test if [ -n "$decrypt" ]; then out="/tmp/bwlp-test-${RANDOM}-$$.tgz" decryptor "$BACKUP" "$out" echo "- Decrypted backup successfully" rm -f -- "$BACKUP" BACKUP="$out" fi num=$( tar tf "$BACKUP" | grep -c -x -F -e "files.tgz" -e "sat.sql" -e "openslx.sql" -e "db.sql" ) rm -f -- "$BACKUP" if (( num < 2 )); then echo "- - -" echo "- This does not look like a .tar.gz containing a Satellite Server backup" exit 1 fi exit 0 # End test fi [ "$RES_OPENSLX$RES_SAT" = "00" ] && exit 1 if [ "$(whoami)" != "root" ]; then echo "Must be running as root!" exit 1 fi slxsql() { mysql --defaults-extra-file=/etc/mysql/debian.cnf --default-character-set=utf8mb4 "$@" } slxsqldump() { mysqldump --defaults-extra-file=/etc/mysql/debian.cnf --default-character-set=utf8mb4 "$@" } cleanup_hook() { rm -rf -- "$DIR" rm -f -- "$BACKUP" } DIR="/root/restore/$(date +%s)" if [ -d "$DIR" ]; then echo "Restore already running!?" exit 1 fi trap cleanup_hook EXIT mkdir -p "$DIR" if ! cd "$DIR"; then echo "Could not cd to $DIR" exit 1 fi # Decrypt if [ -n "$decrypt" ]; then out="${BACKUP%.aes}" [ "$out" = "$BACKUP" ] && out="${BACKUP}.tgz" decryptor "$BACKUP" "$out" rm -f -- "$BACKUP" BACKUP="$out" fi if ! tar --ignore-failed-read -x -f "$BACKUP"; then echo "Could not extract $BACKUP - make sure it's a valid .tar.gz[.aes] / .tgz[.aes]" echo "And that you provide the password in case of .aes" exit 1 fi if [ -f db.sql ]; then DB_OLD=1 elif [ -f openslx.sql ] || [ -f sat.sql ]; then DB_OLD=0 else echo "Error: database dump not found in backup - are you sure this is a valid backup?" exit 1 fi if (( RES_SAT == 1 && DB_OLD == 0 )) && ! [ -f sat.sql ]; then echo "Error: this backup does not contain the dmsd database" echo "Error: cannot restore VM/lecture information" exit 1 fi if (( RES_OPENSLX == 1 && DB_OLD == 0 )) && ! [ -f openslx.sql ]; then echo "Error: this backup does not contain the OpenSLX database" echo "Error: cannot restore satellite configuration" exit 1 fi if (( RES_OPENSLX == 1 )) && ! [ -f files.tgz ]; then echo "Error: files.tgz not found in backup - are your sure this is a valid backup?" exit 1 fi echo "-- Restoring Database" if (( DB_OLD == 1 )); then echo "--- Importing legacy database dump" # Restoring from dozmod v1.0 db slxsql < db.sql RET=$? if (( RES_SAT == 1 )); then echo "--- Trying to convert dozmod data (this might not work too well...)" slxsql < "${TMDIR}/data/dozmod-upgrade.sql" else echo "DROP DATABASE bwLehrpool" | slxsql fi else # Restoring from v1.1+ db RET=0 if (( RES_SAT == 1 )); then echo "--- Importing dozmod database (vms/lectures meta data)" slxsql < sat.sql RET=$? fi if (( RET == 0 && RES_OPENSLX == 1 )); then echo "--- Importing system configuration" # Backup and restore minilinux metadata -- doesn't make sense to import this from the backup mtmp="$( mktemp )" slxsqldump --add-locks openslx minilinux_source minilinux_branch minilinux_version > "${mtmp}" 2> /dev/null mlret=$? slxsql < openslx.sql RET=$? if (( mlret == 0 )); then slxsql --database=openslx -e "DROP TABLE IF EXISTS minilinux_version, minilinux_branch, minilinux_source" slxsql --database=openslx < "${mtmp}" fi rm -f -- "$mtmp" fi fi if (( RET != 0 )); then echo "Error: Restoring database contents failed with exit code $RET" exit 1 fi if (( RES_OPENSLX == 1 )); then echo "-- Restoring system files" # Since we came that far we'll delete some old configs (if existent) rm -rf /opt/ldadp/{configs,pid,logs}/* /opt/openslx/configs/* /srv/openslx/www/boot/default/config.tgz 2> /dev/null # Force triggering IP detection/setting, which should in turn regenerate ldadp configs and launch ldadp instances if applicable slxsql -e "UPDATE openslx.property SET value = 'invalid' WHERE name = 'server-ip' LIMIT 1" tar --ignore-failed-read -x -f files.tgz -C / RET=$? if [ $RET -ne 0 ]; then echo "WARNING: Restoring filesystem contents failed with exit code $RET - backup might be incomplete!" fi # Make sure the directory tree is owned by taskmanager, as tar will create intermediate # directories as owned by root if they do not exist. chown -R taskmanager /srv/openslx/www/boot /opt/openslx/configs # Try to update the db (if required) ( cd /srv/openslx/www/slx-admin && ./install-all ) # legacy config.tgz symlink -> db entry if [ -L "/srv/openslx/www/boot/default/config.tgz" ]; then CONFTGZ=$( readlink /srv/openslx/www/boot/default/config.tgz | sed "s/\\\\/\\\\\\\\/g;s/'/\\\'/g" ) echo "Config.tgz links to '$CONFTGZ'" slxsql -e "INSERT IGNORE INTO openslx.configtgz_location (locationid, configid) SELECT 0, configid FROM openslx.configtgz WHERE filepath = '$CONFTGZ' LIMIT 1" \ || echo "Could not convert default config.tgz setting - do so manually" rm -f -- /srv/openslx/www/boot/default/config.tgz fi sleep 0.5 for i in 1 1 1 1 1 2 2 3 4 END; do CB=$( sudo -u www-data -n php /srv/openslx/www/slx-admin/api.php cb ) [ "$CB" != "True" ] && break [ "$i" = "END" ] && break sleep $i done fi # Sync redirect flag file with setting stored in DB /opt/taskmanager/scripts/install-https --redirect --redirect-only # Run all post-restore scripts for i in /opt/openslx/restore.d/*/init.sh; do [ -x "$i" ] || continue "$i" || echo "ERROR running post-restore script $i: $?" done echo "Success." exit 0