#!/bin/sh # CAS 启动入口: # 1) 从 Nacos 拉取「公共基础配置」(common.properties) 与「CAS 自身配置」(cas-prod.properties) # 2) 用 common.properties 的 MySQL 连接 + cas-prod.properties 的 database 拼出完整 JDBC URL # 3) 写出 /etc/cas/config/cas.properties 后启动 CAS # 说明:CAS 不自建 MySQL,统一读 Nacos 公共配置;库名写在 CAS 自己的配置里。 set -e CONFIG_PATH=/etc/cas/config/cas.properties # 备份镜像内烤好的兜底配置,供 Nacos 不可用时回退 cp -f "$CONFIG_PATH" "${CONFIG_PATH}.baked" 2>/dev/null || true NACOS_ADDR="${NACOS_ADDR:-nacos:8848}" NACOS_USER="${NACOS_USER:-nacos}" NACOS_PASS="${NACOS_PASS:-nacos}" # 公共基础配置(含 mysql / redis / rabbitmq 连接信息) BASE_DATA_ID="${CAS_BASE_CONFIG_DATA_ID:-common.properties}" BASE_GROUP="${CAS_BASE_CONFIG_GROUP:-DEFAULT_GROUP}" BASE_NS="${CAS_BASE_CONFIG_NAMESPACE:-public}" # CAS 自身配置 CAS_DATA_ID="${CAS_CONFIG_DATA_ID:-cas-prod.properties}" CAS_GROUP="${CAS_CONFIG_GROUP:-CAS}" CAS_NS="${CAS_CONFIG_NAMESPACE:-cas}" TOKEN="" # 取 Nacos 登录 token(鉴权关闭时返回空,fetch 会自动降级) get_token() { TOKEN=$(curl -s -m 10 -X POST "http://${NACOS_ADDR}/nacos/v1/auth/login?username=${NACOS_USER}&password=${NACOS_PASS}" \ | sed -n 's/.*"accessToken":"\([^"]*\)".*/\1/p') } # 拉取单个配置到 $4;带 token 失败则自动不带 token 重试 fetch() { local code if [ -n "$TOKEN" ]; then code=$(curl -s -m 10 -o "$4" -w "%{http_code}" "http://${NACOS_ADDR}/nacos/v1/cs/configs?dataId=$1&group=$2&tenant=$3&accessToken=${TOKEN}") fi if [ -z "$TOKEN" ] || [ "$code" != "200" ] || [ ! -s "$4" ]; then code=$(curl -s -m 10 -o "$4" -w "%{http_code}" "http://${NACOS_ADDR}/nacos/v1/cs/configs?dataId=$1&group=$2&tenant=$3") fi if [ "$code" = "200" ] && [ -s "$4" ]; then echo "[run-cas] 已加载 $1 (group=$2, ns=$3)" return 0 fi echo "[run-cas] 拉取 $1 失败 http=${code}" return 1 } # 精确读取 key=value 中的 value(兼容 value 内含 =) val() { awk -v k="$2" 'index($0,"=")>0 && substr($0,1,index($0,"=")-1)==k {print substr($0,index($0,"=")+1); exit}' "$1" } # 读键:优先 spring.datasource.*,回退 mysql.* 风格(兼容两种命名习惯) readkey() { local f="$1" k="$2" v v=$(val "$f" "$k"); [ -n "$v" ] && { echo "$v"; return; } v=$(val "$f" "mysql.${k#spring.datasource.}"); [ -n "$v" ] && { echo "$v"; return; } [ "$k" = "spring.datasource.username" ] && val "$f" "mysql.user" } restore_baked() { echo "[run-cas] 回退到镜像内烤好的默认配置" cp -f "${CONFIG_PATH}.baked" "$CONFIG_PATH" exec java -jar /app/cas.war } get_token BASE_TMP="${CONFIG_PATH}.base" CAS_TMP="${CONFIG_PATH}.cas" # 1) 公共基础配置(MySQL 连接必须在此) if ! fetch "$BASE_DATA_ID" "$BASE_GROUP" "$BASE_NS" "$BASE_TMP"; then echo "[run-cas] 公共配置缺失,无法拼 JDBC,回退兜底" restore_baked fi DS_HOST=$(readkey "$BASE_TMP" "spring.datasource.host") DS_PORT=$(readkey "$BASE_TMP" "spring.datasource.port") [ -z "$DS_PORT" ] && DS_PORT=3306 DS_USER=$(readkey "$BASE_TMP" "spring.datasource.username") DS_PASS=$(readkey "$BASE_TMP" "spring.datasource.password") DS_PARAMS=$(readkey "$BASE_TMP" "spring.datasource.params") [ -z "$DS_PARAMS" ] && DS_PARAMS="useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true" # 占位符保护:common.properties 未替换占位符时明确报错,避免静默用假凭据导致连不上 MySQL case "${DS_USER}${DS_PASS}" in *__SHARED_*) echo "[run-cas] 致命:common.properties 中 MySQL 用户名/密码仍为占位符(__SHARED_*),请在 Nacos 填入真实 mysql8 凭据后再启动"; exit 1 ;; esac # 2) CAS 自身配置(库名 database 在此;缺省回退 bsch_userbase) DB_NAME=bsch_userbase if fetch "$CAS_DATA_ID" "$CAS_GROUP" "$CAS_NS" "$CAS_TMP"; then _db=$(val "$CAS_TMP" "cas.authn.jdbc.query[0].database") [ -n "$_db" ] && DB_NAME="$_db" else echo "[run-cas] CAS 自身配置缺失,database 用默认 bsch_userbase" fi if [ -z "$DS_HOST" ]; then echo "[run-cas] 公共配置缺少 MySQL host,无法拼 JDBC,回退兜底" restore_baked fi # 3) 拼完整 JDBC URL JDBC_URL="jdbc:mysql://${DS_HOST}:${DS_PORT}/${DB_NAME}?${DS_PARAMS}" # 4) 合并:CAS 配置为主,过滤其中旧的 JDBC 连接项,注入公共连接 { if [ -f "$CAS_TMP" ]; then grep -vF 'cas.authn.jdbc.query[0].url=' "$CAS_TMP" \ | grep -vF 'cas.authn.jdbc.query[0].user=' \ | grep -vF 'cas.authn.jdbc.query[0].password=' \ | grep -vF 'cas.authn.jdbc.query[0].driverClass=' fi echo "cas.authn.jdbc.query[0].url=${JDBC_URL}" [ -n "$DS_USER" ] && echo "cas.authn.jdbc.query[0].user=${DS_USER}" [ -n "$DS_PASS" ] && echo "cas.authn.jdbc.query[0].password=${DS_PASS}" echo "cas.authn.jdbc.query[0].driverClass=com.mysql.jdbc.Driver" # 透传公共配置里的 redis / rabbitmq 连接(自定义 /api/login 的 loginService 依赖 Redis 存验证码/失败计数/账号锁定) grep -E '^spring\.redis\.' "$BASE_TMP" 2>/dev/null || true grep -E '^spring\.rabbitmq\.' "$BASE_TMP" 2>/dev/null || true } > "$CONFIG_PATH" echo "[run-cas] 生效 JDBC URL: ${JDBC_URL}" echo "[run-cas] 启动 CAS ..." exec java -jar /app/cas.war