#!/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}'."