环境配置统一以 .env 为单一事实来源,移除 .ctms-env

- 删除 .ctms-env:环境名由 .env 的 COMPOSE_PROJECT_NAME 反推
  (ctms_detect_env),健康检查地址改存 .env 的 CTMS_BASE_URL
- prepare_env_file 由“已存在则整体跳过”改为逐项探测补全:
  身份类缺失补目标值、密钥类缺失/空才生成、已有值一律不动
- resolve_effective_config 放宽为“冲突才致命”:身份类缺失交给
  补全,仅 COMPOSE_PROJECT_NAME/ENV 与目标环境冲突时报错停止
  (防止覆盖后孤立旧环境容器)
- 新增 ctms_env_has_key 区分“键缺失”与“键存在但空值”
  (dev 的 LOGIN_RSA_PRIVATE_KEY= 是合法空值)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Cheng Zhou
2026-06-24 10:48:27 +08:00
parent 24d5b7445f
commit f9a9f7eafe
4 changed files with 94 additions and 81 deletions
+8 -55
View File
@@ -171,16 +171,9 @@ select_menu() {
done
}
# 读取 .ctms-env 中的 KEY = VALUE 配置
ctms_config_get() {
local key="$1" file="$ROOT_DIR/.ctms-env"
[[ -f "$file" ]] || return 1
awk -F' *= *' -v k="$key" 'NF==2 && $1==k { print $2; exit }' "$file"
}
pick_env() {
local env default_index=0
env="$(ctms_config_get "env" || true)"
env="$(ctms_detect_env)"
case "$env" in
main) default_index=1 ;;
release) default_index=2 ;;
@@ -210,44 +203,6 @@ pick_env() {
esac
}
# 把环境持久化到 .ctms-env,仅在操作成功完成后调用。
# 文件不存在则创建(首次安装场景);存在则就地更新 env 行。
# 若本次收集到健康检查地址(SELECTED_BASE_URL),一并写入/更新 base-url。
persist_env() {
local env_to_save="$1"
local file="$ROOT_DIR/.ctms-env"
if [[ ! -f "$file" ]]; then
{
printf 'env = %s\n' "$env_to_save"
[[ -n "${SELECTED_BASE_URL:-}" ]] && printf 'base-url = %s\n' "$SELECTED_BASE_URL"
} >"$file"
ctms_info "已创建 .ctms-env,环境记录为: $env_to_save"
return 0
fi
local current
current="$(ctms_config_get "env" || true)"
if [[ "$current" != "$env_to_save" ]]; then
sed -i.bak "s/^env *=.*/env = $env_to_save/" "$file" && rm -f "${file}.bak"
ctms_info "已将 .ctms-env 中的环境更新为: $env_to_save"
fi
# 同步 base-url:存在则替换该行,不存在则追加
if [[ -n "${SELECTED_BASE_URL:-}" ]]; then
local current_url
current_url="$(ctms_config_get "base-url" || true)"
if [[ "$current_url" != "$SELECTED_BASE_URL" ]]; then
if grep -q '^base-url *=' "$file"; then
sed -i.bak "s|^base-url *=.*|base-url = $SELECTED_BASE_URL|" "$file" && rm -f "${file}.bak"
else
printf 'base-url = %s\n' "$SELECTED_BASE_URL" >>"$file"
fi
ctms_info "已将 .ctms-env 中的健康检查地址更新为: $SELECTED_BASE_URL"
fi
fi
}
# 卸载专用:仅在“实际检测到容器”的环境中选择,避免选到空环境走完确认却什么都没卸。
# 始终弹出选择菜单(哪怕只有一个环境),作为危险确认前的显式安全闸门。
# 返回 0 表示已选定 SELECTED_ENV,返回 1 表示无可卸载环境(调用方应跳过卸载)。
@@ -276,7 +231,7 @@ pick_deployed_env() {
collect_install_options() {
local env="$1"
SELECTED_BASE_URL="$(ctms_config_get "base-url" || true)"
SELECTED_BASE_URL="$(ctms_read_env_value CTMS_BASE_URL || true)"
if [[ "$env" == "release" && -z "$SELECTED_BASE_URL" ]]; then
SELECTED_BASE_URL="$(ctms_ask_line "请输入健康检查地址,例如 https://ctms.example.com")"
@@ -505,9 +460,8 @@ interactive_main() {
pick_env
collect_install_options "$SELECTED_ENV"
BREADCRUMB="${OP_LABEL} ${SELECTED_ENV} 执行中"
if run_install_like_script "install.sh" "$SELECTED_ENV"; then
persist_env "$SELECTED_ENV"
fi
# 环境与健康检查地址由底层 install.sh 写入 .env(单一事实来源);失败不退出控制台。
run_install_like_script "install.sh" "$SELECTED_ENV" || true
pause_return
;;
1)
@@ -520,9 +474,8 @@ interactive_main() {
# 记录更新前 HEAD,用于结束后判断代码是否被改动(决定 stash 能否安全自动恢复)
local head_before_update
head_before_update="$(git -C "$ROOT_DIR" rev-parse HEAD 2>/dev/null || true)"
if run_update_script "$SELECTED_ENV"; then
persist_env "$SELECTED_ENV"
fi
# 环境与健康检查地址由底层 update→install.sh 写入 .env;失败也要继续做 stash 善后。
run_update_script "$SELECTED_ENV" || true
restore_stash_after_update "$head_before_update"
fi
pause_return
@@ -537,9 +490,9 @@ interactive_main() {
;;
3)
OP_LABEL="资源状态"
# 只读快照,无需选环境:直接用 .ctms-env 识别的环境(无配置回退 dev
# 只读快照,无需选环境:从 .env 反推环境(无配置回退 dev
local env_for_status
env_for_status="$(ctms_config_get "env" || true)"
env_for_status="$(ctms_detect_env)"
env_for_status="${env_for_status:-dev}"
BREADCRUMB="${OP_LABEL} ${env_for_status}"
# status.sh 自身是交互循环(q/Enter 退出并清屏),正常退出直接回菜单;