diff --git a/deploy.sh b/deploy.sh index 22648bb..1ee7007 100644 --- a/deploy.sh +++ b/deploy.sh @@ -34,18 +34,18 @@ DAEMON_JSON="/etc/docker/daemon.json" MIRROR_CHECK_TIMEOUT=5 # ---------- 镜像加速状态变量 ---------- -MIRROR_STATUS="" # no_file | no_key | empty_array | has_valid_ordered | has_valid_reorder_needed | all_invalid -DEFAULT_STATUS="" # default_unavailable | default_partial | default_all_available +MIRROR_STATUS="" +DEFAULT_STATUS="" WRITE_DAEMON=false RESTART_DOCKER=false REORDER=false INSERT_DEFAULT=false HAS_REGISTRY_MIRRORS_KEY=false -AVAILABLE_MIRRORS=() # 可用的默认地址 -USER_MIRRORS_AVAILABLE=() # 用户配置中可用的地址 -USER_MIRRORS_UNAVAILABLE=() # 用户配置中不可用的地址 -USER_MIRRORS_ALL=() # 用户配置所有地址(保持原始顺序) -MIRROR_DETECT_OUTPUT="" # 检测阶段输出给用户的描述 +AVAILABLE_MIRRORS=() +USER_MIRRORS_AVAILABLE=() +USER_MIRRORS_UNAVAILABLE=() +USER_MIRRORS_ALL=() +MIRROR_DETECT_OUTPUT="" # ---------- 其他状态变量 ---------- OS=""; OS_VERSION=""; ARCH="" @@ -312,7 +312,6 @@ check_docker_mirrors() { # 8. 判断状态 if [ ${#USER_MIRRORS_AVAILABLE[@]} -gt 0 ]; then - # 检查是否需要重排:是否存在不可用在可用之前 local need_reorder=false local seen_unavailable=false for mirror in "${USER_MIRRORS_ALL[@]}"; do @@ -340,7 +339,6 @@ check_docker_mirrors() { print_info "用户镜像源配置正常,无需调整" fi else - # 用户配置全部不可用 MIRROR_STATUS="all_invalid" print_warn "用户配置全部不可用" fi @@ -352,14 +350,12 @@ check_docker_mirrors() { generate_mirror_detect_output() { MIRROR_DETECT_OUTPUT="" - # 如果默认地址全部不可用,直接输出警告 if [ "$DEFAULT_STATUS" = "default_unavailable" ]; then MIRROR_DETECT_OUTPUT="${MIRROR_DETECT_OUTPUT}${YELLOW}⚠ 所有默认镜像源均不可用,将跳过镜像加速配置${NC}\n" MIRROR_DETECT_OUTPUT="${MIRROR_DETECT_OUTPUT}如果 Docker 构建失败,请检查网络或手动配置镜像源。\n" return fi - # 构建可用地址列表显示 local avail_list="" for m in "${AVAILABLE_MIRRORS[@]}"; do avail_list="${avail_list} ✓ ${m}\n" @@ -475,7 +471,6 @@ generate_mirror_detect_output() { ;; esac - # 打印检测输出 echo "" print_title print_subtitle "Docker 镜像源检测结果" @@ -494,7 +489,6 @@ configure_docker_mirrors() { print_step "配置 Docker 镜像源..." - # 确保 jq 可用 if [ "$HAS_JQ" = false ]; then print_warn "jq 未安装,尝试安装..." if ! install_jq; then @@ -504,7 +498,6 @@ configure_docker_mirrors() { fi fi - # 构建新镜像列表 local new_mirrors=() if [ "$REORDER" = true ]; then new_mirrors=("${USER_MIRRORS_AVAILABLE[@]}" "${USER_MIRRORS_UNAVAILABLE[@]}") @@ -524,113 +517,53 @@ configure_docker_mirrors() { print_info "[反馈] 新镜像列表: ${new_mirrors[*]}" - # ============================================================ - # 确保 daemon.json 存在且为有效 JSON - # ============================================================ - print_info "[反馈] 检查 daemon.json 状态..." - if [ -f "$DAEMON_JSON" ]; then - print_info "[反馈] 文件存在: $DAEMON_JSON" - if [ -s "$DAEMON_JSON" ]; then - print_info "[反馈] 文件大小: $(stat -c%s "$DAEMON_JSON" 2>/dev/null || stat -f%z "$DAEMON_JSON" 2>/dev/null) bytes" - else - print_warn "[反馈] 文件为空 (0 bytes)" - fi - else - print_info "[反馈] 文件不存在" - fi - if ! ensure_daemon_json_valid; then print_error "无法创建或修复 daemon.json" return 1 fi - print_success "[反馈] daemon.json 已就绪 (有效 JSON)" - - # ============================================================ - # 备份 daemon.json(写入前额外备份) - # ============================================================ local backup_path="${DAEMON_JSON}.bak.$(date +%Y%m%d-%H%M%S)" cp "$DAEMON_JSON" "$backup_path" print_info "[反馈] 已备份: $backup_path" - # ============================================================ - # 构建 JSON 镜像数组 - # ============================================================ - print_info "[反馈] 构建 JSON 镜像数组..." local json_mirrors json_mirrors=$(printf '%s\n' "${new_mirrors[@]}" | jq -R . | jq -s . 2>/dev/null) if [ -z "$json_mirrors" ] || [ "$json_mirrors" = "[]" ]; then print_error "[反馈] 构建 JSON 镜像数组失败或为空" - print_error " new_mirrors 内容: ${new_mirrors[*]}" return 1 fi print_info "[反馈] json_mirrors: $json_mirrors" - # ============================================================ - # 写入新配置(仅修改 registry-mirrors 字段,保留其他所有字段) - # ============================================================ print_info "[反馈] 执行 jq 写入操作..." - print_info "[反馈] 源文件: $DAEMON_JSON" - print_info "[反馈] 目标文件: ${DAEMON_JSON}.tmp" - if ! jq --argjson mirrors "$json_mirrors" '."registry-mirrors" = $mirrors' \ "$DAEMON_JSON" > "${DAEMON_JSON}.tmp" 2> "${DAEMON_JSON}.error"; then print_error "[反馈] jq 执行失败" - print_error "[反馈] 错误详情:" if [ -f "${DAEMON_JSON}.error" ]; then + print_error "[反馈] 错误详情:" cat "${DAEMON_JSON}.error" | while read -r line; do print_error " $line" done rm -f "${DAEMON_JSON}.error" fi - print_error "[反馈] 检查文件状态:" - if [ -f "$DAEMON_JSON" ]; then - print_error " 源文件存在,大小: $(stat -c%s "$DAEMON_JSON" 2>/dev/null || stat -f%z "$DAEMON_JSON" 2>/dev/null) bytes" - print_error " 源文件内容预览:" - head -c 200 "$DAEMON_JSON" | while read -r line; do - print_error " $line" - done - else - print_error " 源文件不存在!" - fi - if [ -f "${DAEMON_JSON}.tmp" ]; then - print_error " 临时文件已创建,大小: $(stat -c%s "${DAEMON_JSON}.tmp" 2>/dev/null || stat -f%z "${DAEMON_JSON}.tmp" 2>/dev/null) bytes" - [ -s "${DAEMON_JSON}.tmp" ] && print_error " 临时文件内容: $(cat "${DAEMON_JSON}.tmp")" - fi rm -f "${DAEMON_JSON}.tmp" return 1 fi - # 验证临时文件 - if [ ! -f "${DAEMON_JSON}.tmp" ]; then - print_error "[反馈] 临时文件未生成: ${DAEMON_JSON}.tmp" - return 1 - fi - - if [ ! -s "${DAEMON_JSON}.tmp" ]; then - print_error "[反馈] 临时文件为空: ${DAEMON_JSON}.tmp" + if [ ! -f "${DAEMON_JSON}.tmp" ] || [ ! -s "${DAEMON_JSON}.tmp" ]; then + print_error "[反馈] 临时文件为空或不存在" rm -f "${DAEMON_JSON}.tmp" return 1 fi - print_success "[反馈] jq 执行成功,临时文件已生成 (大小: $(stat -c%s "${DAEMON_JSON}.tmp" 2>/dev/null || stat -f%z "${DAEMON_JSON}.tmp" 2>/dev/null) bytes)" - - # 验证临时文件是否为有效 JSON if ! jq -e '.' "${DAEMON_JSON}.tmp" >/dev/null 2>&1; then print_error "[反馈] 生成的临时文件不是有效的 JSON" - print_error "[反馈] 内容预览:" - head -c 500 "${DAEMON_JSON}.tmp" | while read -r line; do - print_error " $line" - done rm -f "${DAEMON_JSON}.tmp" return 1 fi mv "${DAEMON_JSON}.tmp" "$DAEMON_JSON" print_success "daemon.json 已更新" - print_info "新镜像源列表: ${new_mirrors[*]}" - # 重启 Docker if [ "$RESTART_DOCKER" = true ]; then print_step "重启 Docker 服务..." if systemctl restart docker 2>/dev/null; then @@ -638,7 +571,6 @@ configure_docker_mirrors() { sleep 2 else print_error "Docker 重启失败,请手动重启后重新运行脚本" - print_info "手动重启命令: systemctl restart docker" exit 1 fi fi @@ -779,7 +711,6 @@ print_environment_summary() { # ---------- 部署计划 ---------- generate_plan() { PLAN="" - # 按时间先后顺序排列 if [ "$WRITE_DAEMON" = true ]; then PLAN="${PLAN} • 配置 Docker 镜像源" if [ "$RESTART_DOCKER" = true ]; then @@ -936,16 +867,6 @@ do_deploy() { exit 1 fi - # ----- 停止旧容器 ----- - if [ "$CONTAINER_EXISTS" = true ]; then - print_step "停止旧容器..." - if [ "$CONTAINER_RUNNING" = true ]; then - docker stop frpc-console 2>/dev/null || true - fi - docker rm frpc-console 2>/dev/null || true - print_success "旧容器已清理" - fi - # ----- 准备部署目录 ----- print_step "准备部署目录..." mkdir -p "$DEPLOY_DIR" @@ -1017,6 +938,23 @@ do_deploy() { print_info "已标记 ${IMAGE_NAME}:preview" fi + # ============================================================ + # 强制清理旧容器(独立检测,不依赖之前缓存的变量) + # ============================================================ + print_step "检查并清理旧容器..." + if docker ps -a --format '{{.Names}}' 2>/dev/null | grep -q "^frpc-console$"; then + print_info "检测到已存在的 frpc-console 容器" + if docker ps --format '{{.Names}}' 2>/dev/null | grep -q "^frpc-console$"; then + print_info "容器正在运行,停止中..." + docker stop frpc-console 2>/dev/null || true + fi + print_info "删除旧容器..." + docker rm frpc-console 2>/dev/null || true + print_success "旧容器已清理" + else + print_info "未检测到旧容器" + fi + # ----- 启动新容器 ----- print_step "启动 frpc-console 容器..." docker run -d \ @@ -1146,7 +1084,6 @@ main() { check_tools check_container - # ---------- 镜像源检测(拉取代码前,只检测不修改) ---------- check_docker_mirrors select_channel