Import alt-mysql plugin
This commit is contained in:
@@ -0,0 +1,238 @@
|
||||
#!/bin/bash
|
||||
set -Eeuo pipefail
|
||||
|
||||
ERROR_MSG=""
|
||||
BACKUP_OK=0
|
||||
DA_USER=""
|
||||
DB_NAME=""
|
||||
JOB_ID=""
|
||||
LOG_FILE=""
|
||||
|
||||
JOB_FILE="${1:-}"
|
||||
if [ -z "$JOB_FILE" ] || [ ! -f "$JOB_FILE" ]; then
|
||||
echo "mysql: missing job file" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
PLUGIN_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
CONFIG_FILE="${PLUGIN_DIR}/plugin-settings.conf"
|
||||
LOG_DIR="${PLUGIN_DIR}/data/logs"
|
||||
COMMON_FILE="${PLUGIN_DIR}/scripts/setup/mysql_common.sh"
|
||||
mkdir -p "$LOG_DIR"
|
||||
|
||||
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 0
|
||||
fi
|
||||
|
||||
local subject message
|
||||
if [ "$code" -eq 0 ] && [ "$BACKUP_OK" -eq 1 ]; then
|
||||
subject="Backup bazy MySQL zakończony pomyślnie"
|
||||
message="Backup bazy ${DB_NAME} został wykonany. Plik: ${TARGET_FILE:-nieznany}."
|
||||
else
|
||||
subject="Błąd wykonywania backupu bazy MySQL"
|
||||
if [ -n "$ERROR_MSG" ]; then
|
||||
message="Backup bazy ${DB_NAME} nie powiódł się: ${ERROR_MSG}"
|
||||
else
|
||||
message="Backup bazy ${DB_NAME} nie powiódł się. Sprawdź log zadania."
|
||||
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"
|
||||
}
|
||||
|
||||
fail() {
|
||||
local msg="$1"
|
||||
ERROR_MSG="$msg"
|
||||
if [ -n "${LOG_FILE:-}" ]; then
|
||||
echo "[$(date '+%Y-%m-%d %H:%M:%S')] ERROR: ${msg}" >> "$LOG_FILE"
|
||||
fi
|
||||
}
|
||||
|
||||
log_unexpected_error() {
|
||||
local line_no="$1"
|
||||
local command="$2"
|
||||
local code="$3"
|
||||
if [ -z "${LOG_FILE:-}" ]; then
|
||||
return 0
|
||||
fi
|
||||
if [ -n "${ERROR_MSG:-}" ]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
ERROR_MSG="Nieoczekiwany błąd wykonywania backupu (kod ${code}, linia ${line_no})."
|
||||
echo "[$(date '+%Y-%m-%d %H:%M:%S')] ERROR: ${ERROR_MSG} CMD: ${command}" >> "$LOG_FILE"
|
||||
}
|
||||
|
||||
load_plugin_settings() {
|
||||
if [ ! -f "$CONFIG_FILE" ]; then
|
||||
fail "Brak pliku konfiguracyjnego pluginu: $CONFIG_FILE"
|
||||
exit 1
|
||||
fi
|
||||
# shellcheck disable=SC1090
|
||||
source "$CONFIG_FILE"
|
||||
}
|
||||
|
||||
quote_sh_value() {
|
||||
local value="$1"
|
||||
value="${value//\'/\'\\\'\'}"
|
||||
printf "'%s'" "$value"
|
||||
}
|
||||
|
||||
set_job_var() {
|
||||
local key="$1"
|
||||
local value="$2"
|
||||
local tmp
|
||||
local owner_group=""
|
||||
if [ -f "$JOB_FILE" ]; then
|
||||
owner_group="$(stat -c '%u:%g' "$JOB_FILE" 2>/dev/null || stat -f '%u:%g' "$JOB_FILE" 2>/dev/null || true)"
|
||||
fi
|
||||
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
|
||||
if [ "$(id -u)" -eq 0 ] && [ -n "$owner_group" ]; then
|
||||
chown "$owner_group" "$JOB_FILE" 2>/dev/null || true
|
||||
fi
|
||||
}
|
||||
|
||||
on_exit() {
|
||||
local code="$1"
|
||||
if [ "$code" -ne 0 ] && [ -z "${ERROR_MSG:-}" ] && [ -n "${LOG_FILE:-}" ]; then
|
||||
ERROR_MSG="Zadanie backupu zakończyło się błędem (kod ${code}) bez zarejestrowanego szczegółu."
|
||||
echo "[$(date '+%Y-%m-%d %H:%M:%S')] ERROR: ${ERROR_MSG}" >> "$LOG_FILE"
|
||||
fi
|
||||
notify_user "$code"
|
||||
}
|
||||
trap 'log_unexpected_error "$LINENO" "$BASH_COMMAND" "$?"' ERR
|
||||
trap 'on_exit $?' EXIT
|
||||
|
||||
[ -f "$COMMON_FILE" ] || {
|
||||
echo "Brak helpera MySQL: $COMMON_FILE" >&2
|
||||
exit 1
|
||||
}
|
||||
# shellcheck disable=SC1090
|
||||
source "$COMMON_FILE"
|
||||
|
||||
# shellcheck disable=SC1090
|
||||
source "$JOB_FILE"
|
||||
|
||||
JOB_ID="${JOB_ID:-$(basename "$JOB_FILE" .env)}"
|
||||
DA_USER="${DA_USER:-}"
|
||||
DB_NAME="${DB_NAME:-}"
|
||||
DATE_DIR="${DATE_DIR:-$(date +%Y-%m-%d)}"
|
||||
COMPRESS_BACKUP="${COMPRESS_BACKUP:-1}"
|
||||
USER_BASE_BACKUP_DIR="${USER_BASE_BACKUP_DIR:-/home/${DA_USER}/mysql_backup}"
|
||||
JOB_COMPRESS_BACKUP="${COMPRESS_BACKUP}"
|
||||
JOB_USER_BASE_BACKUP_DIR="${USER_BASE_BACKUP_DIR}"
|
||||
|
||||
LOG_FILE="${LOG_DIR}/${JOB_ID}.log"
|
||||
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Start backup job ${JOB_ID}" > "$LOG_FILE"
|
||||
|
||||
if [ -z "$DA_USER" ] || [ -z "$DB_NAME" ]; then
|
||||
fail "Brak DA_USER lub DB_NAME w pliku zadania."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ "$DB_NAME" != "${DA_USER}_"* ]]; then
|
||||
fail "Baza ${DB_NAME} nie należy do użytkownika ${DA_USER}."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
load_plugin_settings
|
||||
COMPRESS_BACKUP="${JOB_COMPRESS_BACKUP:-$COMPRESS_BACKUP}"
|
||||
USER_BASE_BACKUP_DIR="${JOB_USER_BASE_BACKUP_DIR:-$USER_BASE_BACKUP_DIR}"
|
||||
mysql_load_alt_credentials
|
||||
MYSQL_BIN="$(mysql_alt_binary mysql)" || {
|
||||
fail "Brak binarium mysql."
|
||||
exit 1
|
||||
}
|
||||
MYSQLDUMP_BIN="$(mysql_alt_binary mysqldump)" || {
|
||||
fail "Brak binarium mysqldump."
|
||||
exit 1
|
||||
}
|
||||
mapfile -t MYSQL_ARGS < <(mysql_base_args)
|
||||
|
||||
if [[ "$COMPRESS_BACKUP" =~ ^(true|yes|on)$ ]]; then
|
||||
COMPRESS_BACKUP="1"
|
||||
fi
|
||||
if [[ "$COMPRESS_BACKUP" =~ ^(false|no|off)$ ]]; then
|
||||
COMPRESS_BACKUP="0"
|
||||
fi
|
||||
|
||||
TARGET_DIR="${USER_BASE_BACKUP_DIR%/}/${DATE_DIR}"
|
||||
mkdir -p "$TARGET_DIR"
|
||||
chmod 700 "$TARGET_DIR" 2>/dev/null || true
|
||||
|
||||
if [ "$COMPRESS_BACKUP" = "1" ]; then
|
||||
TARGET_FILE="${TARGET_DIR}/${DB_NAME}.sql.gz"
|
||||
else
|
||||
TARGET_FILE="${TARGET_DIR}/${DB_NAME}.sql"
|
||||
fi
|
||||
TMP_FILE="${TARGET_FILE}.tmp.$$"
|
||||
|
||||
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Backup source DB: ${DB_NAME}" >> "$LOG_FILE"
|
||||
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Backup target file: ${TARGET_FILE}" >> "$LOG_FILE"
|
||||
|
||||
set +e
|
||||
if [ "$COMPRESS_BACKUP" = "1" ]; then
|
||||
MYSQL_PWD="$MYSQL_PASSWORD" "$MYSQLDUMP_BIN" \
|
||||
"${MYSQL_ARGS[@]}" \
|
||||
--single-transaction \
|
||||
--quick \
|
||||
--skip-lock-tables \
|
||||
--routines \
|
||||
--triggers \
|
||||
--events \
|
||||
--default-character-set=utf8mb4 \
|
||||
"$DB_NAME" 2>>"$LOG_FILE" | gzip -c > "$TMP_FILE"
|
||||
RC=${PIPESTATUS[0]}
|
||||
else
|
||||
MYSQL_PWD="$MYSQL_PASSWORD" "$MYSQLDUMP_BIN" \
|
||||
"${MYSQL_ARGS[@]}" \
|
||||
--single-transaction \
|
||||
--quick \
|
||||
--skip-lock-tables \
|
||||
--routines \
|
||||
--triggers \
|
||||
--events \
|
||||
--default-character-set=utf8mb4 \
|
||||
"$DB_NAME" > "$TMP_FILE" 2>>"$LOG_FILE"
|
||||
RC=$?
|
||||
fi
|
||||
set -e
|
||||
|
||||
if [ "$RC" -ne 0 ]; then
|
||||
rm -f "$TMP_FILE"
|
||||
fail "mysqldump zakończył się błędem dla bazy ${DB_NAME}."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mv "$TMP_FILE" "$TARGET_FILE"
|
||||
chmod 600 "$TARGET_FILE" 2>/dev/null || true
|
||||
set_job_var "TARGET_FILE" "$TARGET_FILE"
|
||||
set_job_var "END_TS" "$(date +%s)"
|
||||
|
||||
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Backup completed successfully." >> "$LOG_FILE"
|
||||
BACKUP_OK=1
|
||||
exit 0
|
||||
Reference in New Issue
Block a user