97 lines
3.4 KiB
Bash
97 lines
3.4 KiB
Bash
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
cd "$ROOT_DIR"
|
|
|
|
SOURCE_HOST="${SOURCE_HOST:-}"
|
|
SOURCE_PORT="${SOURCE_PORT:-3306}"
|
|
SOURCE_DATABASE="${SOURCE_DATABASE:-}"
|
|
SOURCE_USER="${SOURCE_USER:-}"
|
|
SOURCE_PASSWORD="${SOURCE_PASSWORD:-}"
|
|
|
|
TARGET_SERVICE="${TARGET_SERVICE:-mysql-debug}"
|
|
TARGET_DATABASE="${TARGET_DATABASE:-}"
|
|
TARGET_USER="${TARGET_USER:-}"
|
|
TARGET_PASSWORD="${TARGET_PASSWORD:-}"
|
|
|
|
FORCE="${FORCE:-0}"
|
|
|
|
if [[ -f ".env" ]]; then
|
|
# shellcheck disable=SC2046
|
|
export $(grep -E '^[A-Za-z_][A-Za-z0-9_]*=' .env | sed 's/\r$//')
|
|
fi
|
|
|
|
SOURCE_HOST="${SOURCE_HOST:-${CONFIG_DB_HOST:-}}"
|
|
SOURCE_DATABASE="${SOURCE_DATABASE:-${CONFIG_DB_DATABASE:-}}"
|
|
SOURCE_USER="${SOURCE_USER:-${CONFIG_DB_USER:-}}"
|
|
SOURCE_PASSWORD="${SOURCE_PASSWORD:-${CONFIG_DB_PASSWORD:-}}"
|
|
|
|
TARGET_DATABASE="${TARGET_DATABASE:-${CONFIG_DB_DEBUG_DATABASE:-}}"
|
|
TARGET_USER="${TARGET_USER:-${CONFIG_DB_DEBUG_USER:-}}"
|
|
TARGET_PASSWORD="${TARGET_PASSWORD:-${CONFIG_DB_DEBUG_PASSWORD:-}}"
|
|
|
|
if [[ -z "${SOURCE_HOST}" || -z "${SOURCE_DATABASE}" || -z "${SOURCE_USER}" || -z "${SOURCE_PASSWORD}" ]]; then
|
|
echo "Missing live DB credentials. Expected CONFIG_DB_HOST/CONFIG_DB_DATABASE/CONFIG_DB_USER/CONFIG_DB_PASSWORD."
|
|
exit 1
|
|
fi
|
|
if [[ -z "${TARGET_DATABASE}" || -z "${TARGET_USER}" || -z "${TARGET_PASSWORD}" ]]; then
|
|
echo "Missing debug DB credentials. Expected CONFIG_DB_DEBUG_DATABASE/CONFIG_DB_DEBUG_USER/CONFIG_DB_DEBUG_PASSWORD."
|
|
exit 1
|
|
fi
|
|
|
|
if ! command -v docker >/dev/null 2>&1; then
|
|
echo "Docker is required but was not found in PATH."
|
|
exit 1
|
|
fi
|
|
|
|
if [[ "${FORCE}" != "1" ]]; then
|
|
echo "This will overwrite debug DB '${TARGET_DATABASE}' in service '${TARGET_SERVICE}' with live DB '${SOURCE_DATABASE}' from '${SOURCE_HOST}'."
|
|
read -r -p "Type CLONE to continue: " confirmation
|
|
if [[ "${confirmation}" != "CLONE" ]]; then
|
|
echo "Cancelled."
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
echo "Starting debug DB service (${TARGET_SERVICE})..."
|
|
docker compose up -d "${TARGET_SERVICE}"
|
|
|
|
echo "Waiting for debug DB to accept connections..."
|
|
for i in $(seq 1 60); do
|
|
if docker compose exec -T "${TARGET_SERVICE}" sh -lc "MYSQL_PWD='${TARGET_PASSWORD}' mysqladmin -u '${TARGET_USER}' ping --silent" >/dev/null 2>&1; then
|
|
break
|
|
fi
|
|
if [[ "$i" -eq 60 ]]; then
|
|
echo "Timed out waiting for ${TARGET_SERVICE} to become ready."
|
|
exit 1
|
|
fi
|
|
sleep 2
|
|
done
|
|
|
|
DUMP_DIR="${ROOT_DIR}/.tmp-db-clone"
|
|
DUMP_FILE="${DUMP_DIR}/live-to-debug.sql"
|
|
mkdir -p "${DUMP_DIR}"
|
|
rm -f "${DUMP_FILE}"
|
|
|
|
echo "Creating live dump..."
|
|
docker run --rm \
|
|
-e "MYSQL_PWD=${SOURCE_PASSWORD}" \
|
|
-v "${DUMP_DIR}:/dump" \
|
|
mysql:8.4 \
|
|
sh -lc "exec mysqldump --compression-algorithms=zstd --single-transaction --quick --set-gtid-purged=OFF -h '${SOURCE_HOST}' -P '${SOURCE_PORT}' -u '${SOURCE_USER}' '${SOURCE_DATABASE}' > /dump/live-to-debug.sql"
|
|
|
|
if [[ ! -f "${DUMP_FILE}" ]]; then
|
|
echo "Database dump failed."
|
|
exit 1
|
|
fi
|
|
|
|
echo "Resetting debug database '${TARGET_DATABASE}'..."
|
|
docker compose exec -T "${TARGET_SERVICE}" sh -lc "MYSQL_PWD='${TARGET_PASSWORD}' mysql -u '${TARGET_USER}' -e \"DROP DATABASE IF EXISTS ${TARGET_DATABASE}; CREATE DATABASE ${TARGET_DATABASE};\""
|
|
|
|
echo "Importing live dump into debug DB..."
|
|
cat "${DUMP_FILE}" | docker compose exec -T "${TARGET_SERVICE}" sh -lc "MYSQL_PWD='${TARGET_PASSWORD}' mysql -u '${TARGET_USER}' '${TARGET_DATABASE}'"
|
|
|
|
rm -f "${DUMP_FILE}"
|
|
echo "Done. Debug DB '${TARGET_DATABASE}' now mirrors live '${SOURCE_DATABASE}'."
|