Wire Doctrine's default connection to the tenant database resolved from the subdomain for HTTP requests and tenant-scoped Messenger messages while keeping master-only services on the master connection. This removes the production inconsistency where demo data, migrations and tenant commands used the tenant database but the web runtime still read from master.
227 lines
5.3 KiB
Bash
Executable File
227 lines
5.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR=$(cd -- "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
|
ROOT_DIR=$(cd -- "${SCRIPT_DIR}/../.." && pwd)
|
|
ENV_FILE="${CLASSEO_ENV_FILE:-${SCRIPT_DIR}/.env}"
|
|
COMPOSE_FILE="${CLASSEO_COMPOSE_FILE:-${ROOT_DIR}/compose.prod.yaml}"
|
|
PHP_SERVICE="${CLASSEO_PHP_SERVICE:-php}"
|
|
|
|
usage() {
|
|
cat <<EOF
|
|
Usage: ./deploy/vps/generate-demo-data.sh [options]
|
|
|
|
Generate a full demo dataset inside the tenant database used by the VPS deployment.
|
|
|
|
Options:
|
|
--tenant SUBDOMAIN Tenant subdomain. Defaults to TENANT_SUBDOMAIN from ${ENV_FILE}.
|
|
--password PASSWORD Shared password for all generated accounts.
|
|
Default: DemoPassword123!
|
|
--school NAME School name displayed on generated accounts.
|
|
--zone ZONE School zone: A, B or C. Default: B
|
|
--period-type TYPE Academic period type: trimester or semester.
|
|
Default: trimester
|
|
--target TARGET Where to write demo data: master or tenant.
|
|
Default: tenant
|
|
--env-file PATH Override env file path. Default: ${ENV_FILE}
|
|
--compose-file PATH Override compose file path. Default: ${COMPOSE_FILE}
|
|
--service NAME Override PHP service name. Default: ${PHP_SERVICE}
|
|
-h, --help Show this help.
|
|
|
|
Examples:
|
|
./deploy/vps/generate-demo-data.sh
|
|
./deploy/vps/generate-demo-data.sh --password 'Demo2026!'
|
|
./deploy/vps/generate-demo-data.sh --tenant demo --school 'College de demo'
|
|
./deploy/vps/generate-demo-data.sh --target master
|
|
EOF
|
|
}
|
|
|
|
prompt_with_default() {
|
|
local label="${1}"
|
|
local default_value="${2:-}"
|
|
local answer
|
|
|
|
if [ -n "${default_value}" ]; then
|
|
printf "%s [%s]: " "${label}" "${default_value}" >&2
|
|
else
|
|
printf "%s: " "${label}" >&2
|
|
fi
|
|
|
|
IFS= read -r answer
|
|
printf '%s\n' "${answer:-${default_value}}"
|
|
}
|
|
|
|
require_file() {
|
|
local path="${1}"
|
|
local label="${2}"
|
|
|
|
if [ ! -f "${path}" ]; then
|
|
echo "Missing ${label}: ${path}" >&2
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
ensure_command() {
|
|
if ! command -v "$1" >/dev/null 2>&1; then
|
|
echo "Required command not found: $1" >&2
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
TENANT=""
|
|
PASSWORD="DemoPassword123!"
|
|
SCHOOL=""
|
|
ZONE="B"
|
|
PERIOD_TYPE="trimester"
|
|
TARGET="tenant"
|
|
|
|
while [ "$#" -gt 0 ]; do
|
|
case "$1" in
|
|
--tenant)
|
|
TENANT="${2:-}"
|
|
shift 2
|
|
;;
|
|
--tenant=*)
|
|
TENANT="${1#*=}"
|
|
shift
|
|
;;
|
|
--password)
|
|
PASSWORD="${2:-}"
|
|
shift 2
|
|
;;
|
|
--password=*)
|
|
PASSWORD="${1#*=}"
|
|
shift
|
|
;;
|
|
--school)
|
|
SCHOOL="${2:-}"
|
|
shift 2
|
|
;;
|
|
--school=*)
|
|
SCHOOL="${1#*=}"
|
|
shift
|
|
;;
|
|
--zone)
|
|
ZONE="${2:-}"
|
|
shift 2
|
|
;;
|
|
--zone=*)
|
|
ZONE="${1#*=}"
|
|
shift
|
|
;;
|
|
--period-type)
|
|
PERIOD_TYPE="${2:-}"
|
|
shift 2
|
|
;;
|
|
--period-type=*)
|
|
PERIOD_TYPE="${1#*=}"
|
|
shift
|
|
;;
|
|
--target)
|
|
TARGET="${2:-}"
|
|
shift 2
|
|
;;
|
|
--target=*)
|
|
TARGET="${1#*=}"
|
|
shift
|
|
;;
|
|
--env-file)
|
|
ENV_FILE="${2:-}"
|
|
shift 2
|
|
;;
|
|
--env-file=*)
|
|
ENV_FILE="${1#*=}"
|
|
shift
|
|
;;
|
|
--compose-file)
|
|
COMPOSE_FILE="${2:-}"
|
|
shift 2
|
|
;;
|
|
--compose-file=*)
|
|
COMPOSE_FILE="${1#*=}"
|
|
shift
|
|
;;
|
|
--service)
|
|
PHP_SERVICE="${2:-}"
|
|
shift 2
|
|
;;
|
|
--service=*)
|
|
PHP_SERVICE="${1#*=}"
|
|
shift
|
|
;;
|
|
-h|--help)
|
|
usage
|
|
exit 0
|
|
;;
|
|
*)
|
|
echo "Unknown option: $1" >&2
|
|
echo >&2
|
|
usage >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
|
|
ensure_command docker
|
|
require_file "${ENV_FILE}" "env file"
|
|
require_file "${COMPOSE_FILE}" "compose file"
|
|
|
|
set -a
|
|
# shellcheck disable=SC1090
|
|
. "${ENV_FILE}"
|
|
set +a
|
|
|
|
if [ -z "${TENANT}" ]; then
|
|
TENANT="${TENANT_SUBDOMAIN:-}"
|
|
fi
|
|
|
|
if [ -z "${TENANT}" ] && [ -t 0 ]; then
|
|
TENANT=$(prompt_with_default "Tenant subdomain" "demo")
|
|
fi
|
|
|
|
if [ -z "${TENANT}" ]; then
|
|
echo "Tenant subdomain is required. Pass --tenant or define TENANT_SUBDOMAIN in ${ENV_FILE}." >&2
|
|
exit 1
|
|
fi
|
|
|
|
case "${TARGET}" in
|
|
master|tenant)
|
|
;;
|
|
*)
|
|
echo "Invalid target: ${TARGET}. Expected 'master' or 'tenant'." >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
if [ -z "${SCHOOL}" ] && [ -t 0 ]; then
|
|
SCHOOL=$(prompt_with_default "School name (optional)" "")
|
|
fi
|
|
|
|
COMMAND=(
|
|
docker compose
|
|
--env-file "${ENV_FILE}"
|
|
-f "${COMPOSE_FILE}"
|
|
exec "${PHP_SERVICE}"
|
|
php bin/console app:dev:generate-demo-data
|
|
"--tenant=${TENANT}"
|
|
"--password=${PASSWORD}"
|
|
"--zone=${ZONE}"
|
|
"--period-type=${PERIOD_TYPE}"
|
|
)
|
|
|
|
if [ "${TARGET}" = "master" ]; then
|
|
COMMAND+=("--internal-run")
|
|
fi
|
|
|
|
if [ -n "${SCHOOL}" ]; then
|
|
COMMAND+=("--school=${SCHOOL}")
|
|
fi
|
|
|
|
echo "Running demo data generator for tenant: ${TENANT}"
|
|
echo "Compose file: ${COMPOSE_FILE}"
|
|
echo "Env file: ${ENV_FILE}"
|
|
echo "Target database: ${TARGET}"
|
|
echo
|
|
|
|
"${COMMAND[@]}"
|