#!/bin/bash set -euo pipefail ERROR_MSG="" SUCCESS_MSG="" RESTORE_OK=0 DA_USER="" PRE_BACKUP_PATH="" LOG_FILE="" TMP_DB_USER="tmprestore" TMP_DB_PASS="" TMP_DB_ACTIVE=0 SECURE_RESTORE="true" SECURE_BACKUP="true" OWN_BACKUP_USER_RESTORE="true" JOB_FILE="${1:-}" if [ -z "$JOB_FILE" ] || [ ! -f "$JOB_FILE" ]; then echo "db-manager: missing job file" >&2 exit 1 fi urlencode() { local s="$1" local out="" local i c for ((i=0; i<${#s}; i++)); do c="${s:i:1}" case "$c" in [a-zA-Z0-9.~_-]) out+="$c" ;; ' ') out+='%20' ;; *) printf -v c '%%%02X' "'$c"; out+="$c" ;; esac done printf '%s' "$out" } notify_user() { local code="$1" if [ -z "${DA_USER:-}" ]; then return fi local subject message if [ "$code" -eq 0 ] && [ "$RESTORE_OK" -eq 1 ]; then subject="Przywracanie bazy danych zakonczone pomyslnie" if [ -n "$PRE_BACKUP_PATH" ]; then message="Przywracanie bazy ${DB_NAME:-} z dumpa ${DATE_DIR:-} zakonczone. Backup przed przywroceniem: ${PRE_BACKUP_PATH}." else message="Przywracanie bazy ${DB_NAME:-} z dumpa ${DATE_DIR:-} zakonczone." fi else subject="Blad przywracania bazy danych" if [ -n "$ERROR_MSG" ]; then message="Blad przywracania: ${ERROR_MSG}" else message="Blad przywracania bazy ${DB_NAME:-}. Log: ${LOG_FILE:-brak}." fi if [ -n "${LOG_FILE:-}" ] && [ -f "$LOG_FILE" ]; then local log_content log_content="$(cat "$LOG_FILE")" message="${message}\n\nLog:\n${log_content}" fi fi local task_queue="/usr/local/directadmin/data/task.queue" local users="select1%3D$(urlencode "$DA_USER")" local line="action=notify&value=users&subject=$(urlencode "$subject")&message=$(urlencode "$message")&users=${users}" printf "%s\n" "$line" >> "$task_queue" } db_lock_path_for_db() { local db_name="$1" local safe safe="$(printf '%s' "$db_name" | tr -c 'A-Za-z0-9_.-' '_')" printf '%s/data/lock/%s.lock' "$PLUGIN_DIR" "$safe" } release_db_lock() { local db_name lock_path db_name="${DB_NAME:-}" if [ -z "$db_name" ] || [ -z "${PLUGIN_DIR:-}" ]; then return 0 fi lock_path="$(db_lock_path_for_db "$db_name")" if [ -f "$lock_path" ]; then rm -f "$lock_path" 2>/dev/null || true fi } on_exit() { local code="$1" cleanup_tmp_db_user notify_user "$code" } trap 'on_exit $?' EXIT # shellcheck disable=SC1090 source "$JOB_FILE" DA_USER="${DA_USER:-}" DB_NAME="${DB_NAME:-}" SOURCE_DB_NAME="${SOURCE_DB_NAME:-}" DATE_DIR="${DATE_DIR:-}" DUMP_FILE="${DUMP_FILE:-}" BACKUP_SOURCE="${BACKUP_SOURCE:-hosting}" if [ -z "$SOURCE_DB_NAME" ]; then SOURCE_DB_NAME="$DB_NAME" fi if [ -z "$DA_USER" ] || [ -z "$DB_NAME" ] || [ -z "$DATE_DIR" ]; then echo "Missing DA_USER, DB_NAME or DATE_DIR in job file" >&2 exit 1 fi JOB_BASE="$(basename "$JOB_FILE")" JOB_ID="${JOB_BASE%%.*}" PLUGIN_DIR="$(cd "$(dirname "$0")/.." && pwd)" CONFIG_FILE="${PLUGIN_DIR}/plugin-settings.conf" LOG_DIR="${PLUGIN_DIR}/data/logs" LOG_FILE="${LOG_DIR}/${JOB_ID}.log" mkdir -p "$LOG_DIR" fail() { local msg="$1" ERROR_MSG="$msg" echo "$msg" >> "$LOG_FILE" } if [ ! -f "$CONFIG_FILE" ]; then fail "Missing ${CONFIG_FILE}" exit 1 fi # shellcheck disable=SC1090 source "$CONFIG_FILE" HITME_SQL_BACKUP_DIR="${HITME_SQL_BACKUP_DIR:-/home/admin/mysql_backups}" USER_SQL_BACKUP_DIR="${USER_SQL_BACKUP_DIR:-/home/da_user/mysql_backups/user_backups}" PRE_RESTORE_BACKUP_DIR="${PRE_RESTORE_BACKUP_DIR:-/home/da_user/mysql_backups/pre_restore_backups}" PRE_RESTORE_USER_BACKUP_DIR="${PRE_RESTORE_USER_BACKUP_DIR:-/home/da_user/mysql_backups/pre_restore_user_backups}" ENABLE_PRE_RESTORE_BACKUP="${ENABLE_PRE_RESTORE_BACKUP:-true}" ENABLE_USER_PRE_RESTORE_BACKUP="${ENABLE_USER_PRE_RESTORE_BACKUP:-true}" SECURE_RESTORE="${SECURE_RESTORE:-true}" SECURE_BACKUP="${SECURE_BACKUP:-true}" OWN_BACKUP_USER_RESTORE="${OWN_BACKUP_USER_RESTORE:-true}" ENABLE_PRE_RESTORE_BACKUP="$(echo "$ENABLE_PRE_RESTORE_BACKUP" | tr '[:upper:]' '[:lower:]')" ENABLE_USER_PRE_RESTORE_BACKUP="$(echo "$ENABLE_USER_PRE_RESTORE_BACKUP" | tr '[:upper:]' '[:lower:]')" SECURE_RESTORE="$(echo "$SECURE_RESTORE" | tr '[:upper:]' '[:lower:]')" SECURE_BACKUP="$(echo "$SECURE_BACKUP" | tr '[:upper:]' '[:lower:]')" OWN_BACKUP_USER_RESTORE="$(echo "$OWN_BACKUP_USER_RESTORE" | tr '[:upper:]' '[:lower:]')" if [ "$ENABLE_PRE_RESTORE_BACKUP" = "1" ] || [ "$ENABLE_PRE_RESTORE_BACKUP" = "yes" ]; then ENABLE_PRE_RESTORE_BACKUP="true" fi if [ "$ENABLE_USER_PRE_RESTORE_BACKUP" = "1" ] || [ "$ENABLE_USER_PRE_RESTORE_BACKUP" = "yes" ]; then ENABLE_USER_PRE_RESTORE_BACKUP="true" fi if [ "$SECURE_RESTORE" = "1" ] || [ "$SECURE_RESTORE" = "yes" ]; then SECURE_RESTORE="true" fi if [ "$SECURE_BACKUP" = "1" ] || [ "$SECURE_BACKUP" = "yes" ]; then SECURE_BACKUP="true" fi if [ "$OWN_BACKUP_USER_RESTORE" = "1" ] || [ "$OWN_BACKUP_USER_RESTORE" = "yes" ]; then OWN_BACKUP_USER_RESTORE="true" fi apply_da_user() { local value="$1" value="${value//DA_USER/$DA_USER}" value="${value//da_user/$DA_USER}" printf '%s' "$value" } enforce_root_backup_tree_ownership() { local root_dir="$1" if [ "$(id -u)" -ne 0 ] || [ -z "$root_dir" ] || [ -L "$root_dir" ]; then return 0 fi mkdir -p "$root_dir" 2>/dev/null || true find "$root_dir" \( -type d -o -type f \) -exec chown root:root {} + 2>/dev/null || true } quote_sh_value() { local value="$1" value="${value//\'/\'\\\'\'}" printf "'%s'" "$value" } set_job_var() { local key="$1" local value="$2" local tmp tmp="$(mktemp)" grep -v "^${key}=" "$JOB_FILE" > "$tmp" 2>/dev/null || true printf "%s=%s\n" "$key" "$(quote_sh_value "$value")" >> "$tmp" mv "$tmp" "$JOB_FILE" chmod 600 "$JOB_FILE" 2>/dev/null || true } USER_SQL_BACKUP_DIR="$(apply_da_user "$USER_SQL_BACKUP_DIR")" PRE_RESTORE_BACKUP_DIR="$(apply_da_user "$PRE_RESTORE_BACKUP_DIR")" PRE_RESTORE_USER_BACKUP_DIR="$(apply_da_user "$PRE_RESTORE_USER_BACKUP_DIR")" MYSQL_BACKUPS_ROOT="$(apply_da_user "/home/da_user/mysql_backups")" enforce_root_backup_tree_ownership "$MYSQL_BACKUPS_ROOT" PRE_RESTORE_TARGET_DIR="$PRE_RESTORE_BACKUP_DIR" if [ "$BACKUP_SOURCE" = "user" ]; then PRE_RESTORE_TARGET_DIR="$PRE_RESTORE_USER_BACKUP_DIR" fi PRE_RESTORE_ENABLED="$ENABLE_PRE_RESTORE_BACKUP" if [ "$BACKUP_SOURCE" = "user" ]; then PRE_RESTORE_ENABLED="$ENABLE_USER_PRE_RESTORE_BACKUP" fi if [[ "$DATE_DIR" == *".."* || "$DATE_DIR" == */* ]]; then fail "Invalid DATE_DIR" exit 1 fi if [[ "$DB_NAME" == *".."* || "$DB_NAME" == */* ]]; then fail "Invalid DB_NAME" exit 1 fi if [[ "$DB_NAME" != "${DA_USER}_"* && "$DB_NAME" != "$DA_USER" ]]; then fail "DB_NAME does not belong to user" exit 1 fi if [[ "$SOURCE_DB_NAME" != "${DA_USER}_"* && "$SOURCE_DB_NAME" != "$DA_USER" ]]; then fail "SOURCE_DB_NAME does not belong to user" exit 1 fi build_tmp_db_user() { local db_name="$1" local cleaned name cleaned="$(printf '%s' "$db_name" | tr -c 'A-Za-z0-9_' '_')" name="dbtmp__${cleaned}" if [ "${#name}" -gt 32 ]; then name="${name:0:32}" fi if [ -z "$name" ]; then name="tmprestore" fi printf '%s' "$name" } TMP_DB_USER="$(build_tmp_db_user "$DB_NAME")" resolve_dump_path() { local source_name="${SOURCE_DB_NAME:-$DB_NAME}" local base_path="${HITME_SQL_BACKUP_DIR%/}/${DATE_DIR}/${source_name}" local candidate="" if [ -n "${DUMP_FILE:-}" ]; then candidate="$DUMP_FILE" if [ -f "$candidate" ]; then printf '%s' "$candidate" return 0 fi fi for candidate in "${base_path}.sql.gz" "${base_path}.gz" "${base_path}.sql"; do if [ -f "$candidate" ]; then printf '%s' "$candidate" return 0 fi done return 1 } path_in_dir() { local path="$1" local dir="$2" local real_path real_dir real_path="$(realpath "$path" 2>/dev/null || true)" real_dir="$(realpath "$dir" 2>/dev/null || true)" if [ -z "$real_path" ] || [ -z "$real_dir" ]; then return 1 fi if [ "$real_path" = "$real_dir" ]; then return 0 fi case "$real_path" in "$real_dir"/*) return 0 ;; esac return 1 } path_in_any_dir() { local path="$1" shift local dir for dir in "$@"; do if [ -n "$dir" ] && path_in_dir "$path" "$dir"; then return 0 fi done return 1 } is_trusted_user_backup_dir() { local slot_dir="$1" local marker owner user uid marker="${slot_dir%/}/.db-manager-owned" if [ -f "$marker" ]; then owner="$(grep -E '^OWNER=' "$marker" 2>/dev/null | tail -n1 | cut -d= -f2- || true)" user="$(grep -E '^DA_USER=' "$marker" 2>/dev/null | tail -n1 | cut -d= -f2- || true)" if [ "$owner" = "db-manager" ] && [ "$user" = "$DA_USER" ]; then return 0 fi fi uid="$(stat -c '%u' "$slot_dir" 2>/dev/null || stat -f '%u' "$slot_dir" 2>/dev/null || echo '')" if [ "$uid" = "0" ]; then return 0 fi return 1 } if ! DUMP_PATH="$(resolve_dump_path)"; then fail "Dump file not found for database ${SOURCE_DB_NAME} in ${HITME_SQL_BACKUP_DIR%/}/${DATE_DIR}" exit 1 fi ALLOWED_DUMP_DIRS=() if [ "$BACKUP_SOURCE" = "user" ]; then ALLOWED_DUMP_DIRS+=("$USER_SQL_BACKUP_DIR" "$PRE_RESTORE_USER_BACKUP_DIR") else ALLOWED_DUMP_DIRS+=("$HITME_SQL_BACKUP_DIR" "$PRE_RESTORE_BACKUP_DIR") fi if ! path_in_any_dir "$DUMP_PATH" "${ALLOWED_DUMP_DIRS[@]}"; then fail "Dump file path is outside allowed directories." exit 1 fi if [ "$BACKUP_SOURCE" = "user" ] && [ "$OWN_BACKUP_USER_RESTORE" = "true" ]; then if ! is_trusted_user_backup_dir "$(dirname "$DUMP_PATH")"; then fail "Nie mozna przywrocic tej kopii zapasowej, poniewaz nie zostala utworzona przez plugin DB-Manager." exit 1 fi fi MYSQL_CONF="/usr/local/directadmin/conf/mysql.conf" if [ ! -f "$MYSQL_CONF" ]; then fail "Missing ${MYSQL_CONF}" exit 1 fi MYSQL_USER="" MYSQL_PASS="" MYSQL_HOST="" MYSQL_PORT="" MYSQL_SOCKET="" while IFS='=' read -r key val; do key="${key%%[[:space:]]*}" val="${val##[[:space:]]}" case "$key" in user) MYSQL_USER="$val" ;; passwd) MYSQL_PASS="$val" ;; host) MYSQL_HOST="$val" ;; port) MYSQL_PORT="$val" ;; socket) MYSQL_SOCKET="$val" ;; esac done < <(grep -v '^[[:space:]]*#' "$MYSQL_CONF" | grep -v '^[[:space:]]*$') MYSQL_OPTS=() if [ -n "$MYSQL_USER" ]; then MYSQL_OPTS+=("-u${MYSQL_USER}") fi if [ -n "$MYSQL_PASS" ]; then MYSQL_OPTS+=("-p${MYSQL_PASS}") fi if [ -n "$MYSQL_HOST" ]; then MYSQL_OPTS+=("-h${MYSQL_HOST}") fi if [ -n "$MYSQL_PORT" ] && [ "$MYSQL_PORT" != "0" ]; then MYSQL_OPTS+=("-P${MYSQL_PORT}") fi if [ -n "$MYSQL_SOCKET" ]; then MYSQL_OPTS+=("--socket=${MYSQL_SOCKET}") fi # Cron from /etc/cron.d may run with a minimal PATH. PATH="/usr/local/mysql/bin:/usr/local/mariadb/bin:/usr/local/bin:/usr/bin:/bin:${PATH:-}" export PATH resolve_bin() { local name path for name in "$@"; do if path="$(command -v "$name" 2>/dev/null)"; then printf '%s' "$path" return 0 fi done return 1 } sql_escape() { local v="$1" v="${v//\\/\\\\}" v="${v//\'/\\\'}" printf '%s' "$v" } random_password() { rand_chars() { local charset="$1" local need="$2" local out="" chunk while [ "${#out}" -lt "$need" ]; do chunk="$(LC_ALL=C tr -dc "$charset" /dev/null | head -c $((need - ${#out})) || true)" if [ -z "$chunk" ]; then break fi out+="$chunk" done printf '%s' "$out" } local lower='abcdefghijklmnopqrstuvwxyz' local upper='ABCDEFGHIJKLMNOPQRSTUVWXYZ' local digits='0123456789' local special='-' local all="${lower}${upper}${digits}${special}" local seed extra mixed out tmp local -a chars=() local i j seed="$(rand_chars "$lower" 1)$(rand_chars "$upper" 1)$(rand_chars "$digits" 1)$(rand_chars "$special" 1)" extra="$(rand_chars "$all" 20)" mixed="${seed}${extra}" if [ "${#mixed}" -lt 24 ]; then mixed="aA1-" while [ "${#mixed}" -lt 24 ]; do mixed="${mixed}aA1-" done mixed="${mixed:0:24}" fi for ((i=0; i<${#mixed}; i++)); do chars+=("${mixed:i:1}") done for ((i=${#chars[@]}-1; i>0; i--)); do j=$((RANDOM % (i + 1))) tmp="${chars[i]}" chars[i]="${chars[j]}" chars[j]="$tmp" done out="" for tmp in "${chars[@]}"; do out+="$tmp" done printf '%s' "${out:0:24}" } cleanup_tmp_db_user() { if [ "${TMP_DB_ACTIVE:-0}" -ne 1 ]; then return fi if [ -z "${MYSQL_BIN:-}" ]; then return fi local user_esc sql user_esc="$(sql_escape "$TMP_DB_USER")" sql=" DROP USER IF EXISTS '${user_esc}'@'localhost'; DROP USER IF EXISTS '${user_esc}'@'127.0.0.1'; FLUSH PRIVILEGES;" set +e "${MYSQL_BIN}" "${MYSQL_OPTS[@]}" -e "$sql" >>"$LOG_FILE" 2>&1 set -e TMP_DB_ACTIVE=0 } create_tmp_db_user_for_restore() { TMP_DB_PASS="$(random_password)" local user_esc pass_esc db_esc sql user_esc="$(sql_escape "$TMP_DB_USER")" pass_esc="$(sql_escape "$TMP_DB_PASS")" db_esc="${DB_NAME//\`/\`\`}" sql=" DROP USER IF EXISTS '${user_esc}'@'localhost'; DROP USER IF EXISTS '${user_esc}'@'127.0.0.1'; CREATE USER '${user_esc}'@'localhost' IDENTIFIED BY '${pass_esc}'; CREATE USER '${user_esc}'@'127.0.0.1' IDENTIFIED BY '${pass_esc}'; GRANT ALL PRIVILEGES ON \`${db_esc}\`.* TO '${user_esc}'@'localhost'; GRANT ALL PRIVILEGES ON \`${db_esc}\`.* TO '${user_esc}'@'127.0.0.1'; FLUSH PRIVILEGES;" set +e "${MYSQL_BIN}" "${MYSQL_OPTS[@]}" -e "$sql" >>"$LOG_FILE" 2>&1 local rc=$? set -e if [ "$rc" -ne 0 ]; then return 1 fi TMP_DB_ACTIVE=1 return 0 } sanitize_sql_stream_for_target_db() { local src_db="$1" local dst_db="$2" local marker_file="${3:-}" awk -v src_db="$src_db" -v dst_db="$dst_db" -v marker_file="$marker_file" ' function escape_ere(str, out, i, ch) { out = "" for (i = 1; i <= length(str); i++) { ch = substr(str, i, 1) if (ch ~ /[][(){}.^$*+?|\\]/) { out = out "\\" ch } else { out = out ch } } return out } BEGIN { src_bt = "`" src_db "`" dst_bt = "`" dst_db "`" src_bt_ere = escape_ere(src_bt) fq_pattern = src_bt_ere "[[:space:]]*\\.[[:space:]]*`" changed = 0 needs_db_replace = (src_db != dst_db) } { line = $0 lower = tolower(line) if (lower ~ /^[[:space:]]*create[[:space:]]+database[[:space:]]+/) { changed = 1 next } if (lower ~ /^[[:space:]]*\/\*![0-9]+[[:space:]]+create[[:space:]]+database[[:space:]]+/) { changed = 1 next } if (lower ~ /^[[:space:]]*drop[[:space:]]+database([[:space:]]+if[[:space:]]+exists)?[[:space:]]+/) { changed = 1 next } if (lower ~ /^[[:space:]]*\/\*![0-9]+[[:space:]]+drop[[:space:]]+database([[:space:]]+if[[:space:]]+exists)?[[:space:]]+/) { changed = 1 next } if (lower ~ /^[[:space:]]*use[[:space:]]+/ || lower ~ /^[[:space:]]*\/\*![0-9]+[[:space:]]+use[[:space:]]+/) { changed = 1 print "USE " dst_bt ";" next } if (needs_db_replace) { if (gsub(fq_pattern, dst_bt ".`", line) > 0) { changed = 1 } } print line } END { if (marker_file != "") { if (changed) { print "1" > marker_file } else { print "0" > marker_file } } } ' } if ! MYSQL_BIN="$(resolve_bin mysql mariadb)"; then fail "mysql client not found (checked: mysql, mariadb; PATH=${PATH})" exit 1 fi MYSQL_ADMIN_CMD=("$MYSQL_BIN" "${MYSQL_OPTS[@]}") MYSQL_RESTORE_CMD=("${MYSQL_ADMIN_CMD[@]}") MYSQLDUMP_BIN="" MYSQL_PREBACKUP_DUMP_CMD=() if [ "$PRE_RESTORE_ENABLED" = "true" ]; then if ! MYSQLDUMP_BIN="$(resolve_bin mysqldump mariadb-dump)"; then fail "mysqldump client not found (checked: mysqldump, mariadb-dump; PATH=${PATH})" exit 1 fi MYSQL_PREBACKUP_DUMP_CMD=("$MYSQLDUMP_BIN" "${MYSQL_OPTS[@]}" --single-transaction --routines --events --triggers) fi NEED_TMP_USER=0 if [ "$SECURE_RESTORE" = "true" ]; then NEED_TMP_USER=1 fi if [ "$PRE_RESTORE_ENABLED" = "true" ] && [ "$SECURE_BACKUP" = "true" ]; then NEED_TMP_USER=1 fi if [ "$NEED_TMP_USER" -eq 1 ]; then if ! create_tmp_db_user_for_restore; then fail "Nie udalo sie utworzyc tymczasowego uzytkownika bazy." exit 1 fi TMP_CONN_OPTS=("-u${TMP_DB_USER}" "-p${TMP_DB_PASS}") if [ -n "$MYSQL_SOCKET" ]; then TMP_CONN_OPTS+=("--socket=${MYSQL_SOCKET}" "-hlocalhost") else TMP_CONN_OPTS+=("-h127.0.0.1") if [ -n "$MYSQL_PORT" ] && [ "$MYSQL_PORT" != "0" ]; then TMP_CONN_OPTS+=("-P${MYSQL_PORT}") fi fi if [ "$SECURE_RESTORE" = "true" ]; then MYSQL_RESTORE_CMD=("$MYSQL_BIN" "${TMP_CONN_OPTS[@]}") fi if [ "$PRE_RESTORE_ENABLED" = "true" ] && [ "$SECURE_BACKUP" = "true" ]; then MYSQL_PREBACKUP_DUMP_CMD=("$MYSQLDUMP_BIN" "${TMP_CONN_OPTS[@]}" --single-transaction --routines --events --triggers) fi fi if [ "$SECURE_RESTORE" = "true" ]; then echo "Tryb bezpieczny przywracania: ON (tymczasowy uzytkownik bazy)" >> "$LOG_FILE" else echo "Tryb bezpieczny przywracania: OFF" >> "$LOG_FILE" fi if [ "$PRE_RESTORE_ENABLED" = "true" ]; then if [ "$SECURE_BACKUP" = "true" ]; then echo "Tryb bezpieczny backupu przed przywroceniem: ON (tymczasowy uzytkownik bazy)" >> "$LOG_FILE" else echo "Tryb bezpieczny backupu przed przywroceniem: OFF" >> "$LOG_FILE" fi fi if [ "$PRE_RESTORE_ENABLED" = "true" ]; then DB_NAME_SQL="${DB_NAME//\'/\\\'}" set +e DB_EXISTS="$(${MYSQL_ADMIN_CMD[@]} -N -B -e "SHOW DATABASES LIKE '${DB_NAME_SQL}'" 2>>"$LOG_FILE")" EXISTS_CODE=$? set -e if [ "$EXISTS_CODE" -ne 0 ]; then fail "Nie udalo sie sprawdzic istnienia bazy ${DB_NAME}." exit 1 fi if [ -n "$DB_EXISTS" ]; then mkdir -p "$PRE_RESTORE_TARGET_DIR" chmod 700 "$PRE_RESTORE_TARGET_DIR" || true BACKUP_DATE="$(date +%d-%m-%Y)" BASE_NAME="${DB_NAME}_przed_przywroceniem_${BACKUP_DATE}" TARGET_PATH="${PRE_RESTORE_TARGET_DIR%/}/${BASE_NAME}.sql.gz" IDX=1 while [ -e "$TARGET_PATH" ]; do TARGET_PATH="${PRE_RESTORE_TARGET_DIR%/}/${BASE_NAME}_${IDX}.sql.gz" IDX=$((IDX+1)) done set +e ${MYSQL_PREBACKUP_DUMP_CMD[@]} --databases "$DB_NAME" 2>>"$LOG_FILE" | gzip -c > "$TARGET_PATH" DUMP_CODE=$? set -e if [ "$DUMP_CODE" -ne 0 ]; then rm -f "$TARGET_PATH" fail "Nie udalo sie wykonac backupu bazy ${DB_NAME}." exit 1 fi if [ "$(id -u)" -eq 0 ]; then chown root:root "$PRE_RESTORE_TARGET_DIR" "$TARGET_PATH" 2>/dev/null || true chmod 700 "$PRE_RESTORE_TARGET_DIR" 2>/dev/null || true chmod 600 "$TARGET_PATH" 2>/dev/null || true else chown "${DA_USER}:${DA_USER}" "$TARGET_PATH" 2>/dev/null || true fi enforce_root_backup_tree_ownership "$MYSQL_BACKUPS_ROOT" PRE_BACKUP_PATH="$TARGET_PATH" set_job_var "PRE_BACKUP_PATH" "$PRE_BACKUP_PATH" echo "Wykonano backup przed przywroceniem: ${PRE_BACKUP_PATH}" >> "$LOG_FILE" else echo "Baza ${DB_NAME} nie istnieje - pomijam backup przed przywroceniem." >> "$LOG_FILE" fi else echo "Backup przed przywroceniem jest wylaczony dla tego typu przywracania." >> "$LOG_FILE" fi DB_NAME_BT="${DB_NAME//\`/\`\`}" ${MYSQL_ADMIN_CMD[@]} -e "CREATE DATABASE IF NOT EXISTS \`${DB_NAME_BT}\`" >> "$LOG_FILE" 2>&1 set +e SANITIZE_MARKER_FILE="$(mktemp)" printf "0\n" > "$SANITIZE_MARKER_FILE" if [ "$SOURCE_DB_NAME" != "$DB_NAME" ]; then echo "Sanityzacja dumpa przed importem: ${SOURCE_DB_NAME} -> ${DB_NAME}" >> "$LOG_FILE" fi if [[ "$DUMP_PATH" == *.gz ]]; then gunzip -c "$DUMP_PATH" \ | sanitize_sql_stream_for_target_db "$SOURCE_DB_NAME" "$DB_NAME" "$SANITIZE_MARKER_FILE" \ | ${MYSQL_RESTORE_CMD[@]} --database="$DB_NAME" --verbose >> "$LOG_FILE" 2>&1 RESTORE_CODE=$? else cat "$DUMP_PATH" \ | sanitize_sql_stream_for_target_db "$SOURCE_DB_NAME" "$DB_NAME" "$SANITIZE_MARKER_FILE" \ | ${MYSQL_RESTORE_CMD[@]} --database="$DB_NAME" --verbose >> "$LOG_FILE" 2>&1 RESTORE_CODE=$? fi set -e SANITIZATION_REQUIRED="Nie" if [ -r "$SANITIZE_MARKER_FILE" ]; then if grep -q '^1$' "$SANITIZE_MARKER_FILE"; then SANITIZATION_REQUIRED="Tak" fi fi rm -f "$SANITIZE_MARKER_FILE" set_job_var "SANITIZATION_REQUIRED" "$SANITIZATION_REQUIRED" echo "Koniecznosc Sanityzacji: ${SANITIZATION_REQUIRED}" >> "$LOG_FILE" if [ "$RESTORE_CODE" -ne 0 ]; then fail "Przywracanie bazy ${DB_NAME} zakonczone bledem." exit 1 fi RESTORE_OK=1 SUCCESS_MSG="Przywracanie bazy ${DB_NAME} zakonczone pomyslnie." echo "$SUCCESS_MSG" >> "$LOG_FILE" exit 0