Issues found during P5-01 acceptance testing on WSL2: configure.sh: sync MySQL/Redis host/port into config/xuqm.env (was only writing to .env, leaving xuqm.env with hardcoded 127.0.0.1). install.sh: add docker login step before compose up; reads REGISTRY_USER/REGISTRY_PASSWORD from .env; --skip-registry-login flag for offline bundles or pre-authenticated environments. healthcheck.sh: move docs-site from required to optional container list (image may not exist in all ACR namespaces); add localhost fallback URL for actuator/health when CONSOLE_DOMAIN is not set; add PRIVATE mode verification via /api/private/deployment/status. scripts/migrate-tenant.sh (new): migrates a single tenant from the public platform MySQL to the private deployment. Exports t_tenant, t_app, t_feature_service with explicit column names to survive schema-order differences; supports --dry-run, --reset-password, managed/external destination MySQL, and restarts tenant-service after applying. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
132 行
3.7 KiB
Bash
可执行文件
132 行
3.7 KiB
Bash
可执行文件
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
. "$ROOT_DIR/scripts/lib.sh"
|
|
load_env
|
|
|
|
if [ ! -f "$ROOT_DIR/.env" ]; then
|
|
cp "$ROOT_DIR/.env.example" "$ROOT_DIR/.env"
|
|
fi
|
|
ensure_secret_file
|
|
load_env
|
|
|
|
PROFILE="${COMPOSE_PROFILES:-base}"
|
|
OFFLINE_BUNDLE=""
|
|
SKIP_LOGIN=false
|
|
|
|
usage() {
|
|
cat <<'EOF'
|
|
Usage: ./scripts/install.sh [options]
|
|
|
|
Options:
|
|
--profile <profiles> Docker Compose profiles, for example: base,im,push,update,license
|
|
--mysql-mode <mode> external or managed
|
|
--redis-mode <mode> external or managed
|
|
--offline-bundle <path> Load images from an offline bundle before deployment
|
|
--skip-registry-login Skip docker login (use when already logged in or in offline mode)
|
|
-h, --help Show help
|
|
EOF
|
|
}
|
|
|
|
while [ "$#" -gt 0 ]; do
|
|
case "$1" in
|
|
--skip-registry-login)
|
|
SKIP_LOGIN=true
|
|
shift
|
|
;;
|
|
--profile)
|
|
PROFILE="${2:-}"
|
|
shift 2
|
|
;;
|
|
--profile=*)
|
|
PROFILE="${1#--profile=}"
|
|
shift
|
|
;;
|
|
--mysql-mode)
|
|
MYSQL_MODE="${2:-}"
|
|
set_env_value "$ROOT_DIR/.env" "MYSQL_MODE" "$MYSQL_MODE"
|
|
set_env_value "$ROOT_DIR/config/infra.env" "MYSQL_MODE" "$MYSQL_MODE"
|
|
shift 2
|
|
;;
|
|
--mysql-mode=*)
|
|
MYSQL_MODE="${1#--mysql-mode=}"
|
|
set_env_value "$ROOT_DIR/.env" "MYSQL_MODE" "$MYSQL_MODE"
|
|
set_env_value "$ROOT_DIR/config/infra.env" "MYSQL_MODE" "$MYSQL_MODE"
|
|
shift
|
|
;;
|
|
--redis-mode)
|
|
REDIS_MODE="${2:-}"
|
|
set_env_value "$ROOT_DIR/.env" "REDIS_MODE" "$REDIS_MODE"
|
|
set_env_value "$ROOT_DIR/config/infra.env" "REDIS_MODE" "$REDIS_MODE"
|
|
shift 2
|
|
;;
|
|
--redis-mode=*)
|
|
REDIS_MODE="${1#--redis-mode=}"
|
|
set_env_value "$ROOT_DIR/.env" "REDIS_MODE" "$REDIS_MODE"
|
|
set_env_value "$ROOT_DIR/config/infra.env" "REDIS_MODE" "$REDIS_MODE"
|
|
shift
|
|
;;
|
|
--offline-bundle)
|
|
OFFLINE_BUNDLE="${2:-}"
|
|
shift 2
|
|
;;
|
|
--offline-bundle=*)
|
|
OFFLINE_BUNDLE="${1#--offline-bundle=}"
|
|
shift
|
|
;;
|
|
-h|--help)
|
|
usage
|
|
exit 0
|
|
;;
|
|
*)
|
|
fail_json "XUQM_PRIVATE_4002" "unknown install option: $1" "install"
|
|
;;
|
|
esac
|
|
done
|
|
|
|
[ -n "$PROFILE" ] || fail_json "XUQM_PRIVATE_4003" "profile cannot be empty" "install"
|
|
set_env_value "$ROOT_DIR/.env" "COMPOSE_PROFILES" "$PROFILE"
|
|
|
|
audit "install" "STARTED" "profile=$PROFILE"
|
|
progress "install" "STARTED" "profile=$PROFILE"
|
|
|
|
require_cmd docker
|
|
|
|
if [ -n "$OFFLINE_BUNDLE" ]; then
|
|
[ -f "$OFFLINE_BUNDLE" ] || fail_json "XUQM_PRIVATE_4004" "offline bundle not found: $OFFLINE_BUNDLE" "install"
|
|
docker load -i "$OFFLINE_BUNDLE"
|
|
SKIP_LOGIN=true
|
|
fi
|
|
|
|
# Login to image registry (skip for offline bundles or when already authenticated)
|
|
if [ "$SKIP_LOGIN" = "false" ] && [ -n "${REGISTRY:-}" ]; then
|
|
REGISTRY_HOST="$(printf '%s' "$REGISTRY" | cut -d/ -f1)"
|
|
REGISTRY_USER="${REGISTRY_USER:-}"
|
|
REGISTRY_PASSWORD="${REGISTRY_PASSWORD:-}"
|
|
if [ -n "$REGISTRY_USER" ] && [ -n "$REGISTRY_PASSWORD" ]; then
|
|
printf '%s' "$REGISTRY_PASSWORD" | \
|
|
docker login "$REGISTRY_HOST" -u "$REGISTRY_USER" --password-stdin \
|
|
|| fail_json "XUQM_PRIVATE_4005" "docker login failed for $REGISTRY_HOST" "install"
|
|
audit "install" "REGISTRY_LOGIN_OK" "host=$REGISTRY_HOST"
|
|
else
|
|
audit "install" "REGISTRY_LOGIN_SKIPPED" "REGISTRY_USER/REGISTRY_PASSWORD not set; assuming pre-authenticated"
|
|
fi
|
|
fi
|
|
|
|
if [ "${MYSQL_MODE:-external}" = "managed" ]; then
|
|
"$ROOT_DIR/scripts/install-mysql.sh"
|
|
fi
|
|
|
|
if [ "${REDIS_MODE:-external}" = "managed" ]; then
|
|
"$ROOT_DIR/scripts/install-redis.sh"
|
|
fi
|
|
|
|
"$ROOT_DIR/scripts/render-config.sh"
|
|
|
|
COMPOSE_PROFILES="$PROFILE" compose up -d
|
|
"$ROOT_DIR/scripts/healthcheck.sh"
|
|
|
|
audit "install" "DONE" "profile=$PROFILE"
|
|
progress "install" "DONE" "profile=$PROFILE"
|