#!/usr/bin/env bash # ============================================================================= # check-conn.sh — 验证远程服务连接(MongoDB、MinIO、build-server S3) # # 用法: # ./check-conn.sh # 同时检查 MongoDB 与对象存储 # ./check-conn.sh mongo # 只检查 MongoDB # ./check-conn.sh s3 # 只检查 MinIO(openim)与 S3(build) # # 环境: # CHECK_CONN_AUTO_INSTALL=1 以 root 运行时尝试用 apt/dnf/yum 安装 awscli、mongosh(可选) # ============================================================================= set -euo pipefail source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/common.sh" load_env init_script_log # ← 脚本执行日志 TARGET="${1:-all}" # ── 按系统给出安装提示(避免在 Linux 服务器上误导为 brew)────────────────────── _hint_install_mongosh() { if [[ "$(uname -s)" == "Darwin" ]]; then echo "brew install mongosh" elif command -v apt-get &>/dev/null; then echo "Debian/Ubuntu 默认源通常无 mongodb-mongosh:添加 MongoDB 官方 apt 源后安装,或 snap install mongosh。文档: https://www.mongodb.com/docs/mongodb-shell/install/" elif command -v dnf &>/dev/null; then echo "sudo dnf install -y mongodb-mongosh (若无包见官方文档)" else echo "https://www.mongodb.com/docs/mongodb-shell/install/" fi } # root + apt:添加 MongoDB 8.0 官方源后安装 mongodb-mongosh(Ubuntu/Debian) _try_add_mongodb_apt_repo_and_install_mongosh() { [[ -f /etc/os-release ]] || return 1 # shellcheck source=/dev/null source /etc/os-release local codename="${VERSION_CODENAME:-}" [[ -n "$codename" ]] || return 1 local gpg=/usr/share/keyrings/mongodb-server-8.0.gpg local list=/etc/apt/sources.list.d/mongodb-org-8.0.list local deb_line="" case "${ID:-}" in ubuntu) deb_line="deb [ signed-by=${gpg} ] https://repo.mongodb.org/apt/ubuntu ${codename}/mongodb-org/8.0 multiverse" ;; debian) deb_line="deb [ signed-by=${gpg} ] https://repo.mongodb.org/apt/debian ${codename}/mongodb-org/8.0 main" ;; *) return 1 ;; esac DEBIAN_FRONTEND=noninteractive apt-get install -y -qq curl ca-certificates gnupg >/dev/null 2>&1 || true curl -fsSL https://www.mongodb.org/static/pgp/server-8.0.asc | gpg -o "$gpg" --dearmor 2>/dev/null || return 1 echo "$deb_line" > "$list" DEBIAN_FRONTEND=noninteractive apt-get update -qq || return 1 DEBIAN_FRONTEND=noninteractive apt-get install -y mongodb-mongosh || return 1 return 0 } _hint_install_awscli() { if [[ "$(uname -s)" == "Darwin" ]]; then echo "brew install awscli" elif command -v apt-get &>/dev/null; then echo "若 apt 无 awscli 包:使用 AWS CLI v2 官方 bundle(需 curl+unzip)见 https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html" elif command -v dnf &>/dev/null; then echo "sudo dnf install -y aws-cli" elif command -v yum &>/dev/null; then echo "sudo yum install -y aws-cli" else echo "https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html" fi } # root:从 AWS 官方 zip 安装 CLI v2(适用于 apt 无 awscli 包的 Ubuntu/Debian 等) _try_install_awscli_via_v2_bundle() { local arch zipname arch=$(uname -m) case "$arch" in x86_64) zipname=awscli-exe-linux-x86_64.zip ;; aarch64) zipname=awscli-exe-linux-aarch64.zip ;; *) return 1 ;; esac local tmp tmp=$(mktemp -d) if command -v apt-get &>/dev/null; then DEBIAN_FRONTEND=noninteractive apt-get install -y -qq curl unzip ca-certificates >/dev/null 2>&1 || true fi if ! curl -fsSL "https://awscli.amazonaws.com/${zipname}" -o "${tmp}/awscliv2.zip"; then rm -rf "$tmp" return 1 fi if ! unzip -q "${tmp}/awscliv2.zip" -d "$tmp"; then rm -rf "$tmp" return 1 fi if ! "${tmp}/aws/install"; then rm -rf "$tmp" return 1 fi rm -rf "$tmp" hash -r 2>/dev/null || true command -v aws &>/dev/null } # root + CHECK_CONN_AUTO_INSTALL=1 时尝试安装(失败则仅告警,不退出) _try_install_mongosh() { [[ "${CHECK_CONN_AUTO_INSTALL:-0}" == "1" ]] || return 0 command -v mongosh &>/dev/null && return 0 [[ "$(id -u)" -eq 0 ]] || { info "CHECK_CONN_AUTO_INSTALL=1 但非 root,跳过 mongosh 自动安装" return 0 } info "CHECK_CONN_AUTO_INSTALL:尝试安装 mongosh ..." if command -v apt-get &>/dev/null; then if DEBIAN_FRONTEND=noninteractive apt-get update -qq \ && DEBIAN_FRONTEND=noninteractive apt-get install -y mongodb-mongosh; then command -v mongosh &>/dev/null && success "mongosh 已可用" && return 0 fi if command -v snap &>/dev/null && snap install mongosh; then command -v mongosh &>/dev/null && success "mongosh 已可用 (snap)" && return 0 fi info "尝试通过 MongoDB 官方 apt 源安装 mongodb-mongosh ..." if _try_add_mongodb_apt_repo_and_install_mongosh; then command -v mongosh &>/dev/null && success "mongosh 已可用 (MongoDB 官方源)" && return 0 fi elif command -v dnf &>/dev/null; then if dnf install -y mongodb-mongosh; then command -v mongosh &>/dev/null && success "mongosh 已可用" && return 0 fi fi warn "mongosh 自动安装未成功,请手动: $(_hint_install_mongosh)" return 0 } _try_install_awscli() { [[ "${CHECK_CONN_AUTO_INSTALL:-0}" == "1" ]] || return 0 command -v aws &>/dev/null && return 0 [[ "$(id -u)" -eq 0 ]] || { info "CHECK_CONN_AUTO_INSTALL=1 但非 root,跳过 awscli 自动安装" return 0 } info "CHECK_CONN_AUTO_INSTALL:尝试安装 awscli ..." if command -v apt-get &>/dev/null; then DEBIAN_FRONTEND=noninteractive apt-get update -qq \ && DEBIAN_FRONTEND=noninteractive apt-get install -y awscli || true elif command -v dnf &>/dev/null; then dnf install -y aws-cli || true elif command -v yum &>/dev/null; then yum install -y aws-cli || true fi if command -v aws &>/dev/null; then success "awscli 已可用 (系统包管理器)" return 0 fi info "系统源无 aws/awscli 或安装失败,尝试 AWS CLI v2 官方安装包(需联网)..." if _try_install_awscli_via_v2_bundle; then command -v aws &>/dev/null && success "awscli 已可用 (AWS 官方 bundle)" && return 0 fi warn "awscli 自动安装未成功,请手动: $(_hint_install_awscli)" return 0 } header "远程服务连接检查" # ────────────────────────────────────────────────────────────────────────────── # MongoDB # ────────────────────────────────────────────────────────────────────────────── check_mongo() { _try_install_mongosh step "MongoDB: ${MONGO_HOST}:${MONGO_PORT}/${MONGO_DATABASE}" echo -e " Host: ${MONGO_HOST}" echo -e " Port: ${MONGO_PORT}" echo -e " Database: ${MONGO_DATABASE}" echo -e " AuthSource: ${MONGO_AUTHSOURCE}" echo -e " Username: ${MONGO_USERNAME}" echo "" MONGO_URI="mongodb://${MONGO_USERNAME}:${MONGO_PASSWORD}@${MONGO_HOST}:${MONGO_PORT}/${MONGO_DATABASE}?authSource=${MONGO_AUTHSOURCE}&directConnection=true" # 方法1:mongosh if command -v mongosh &>/dev/null; then info "使用 mongosh 验证..." if mongosh "$MONGO_URI" --quiet --eval \ 'db.runCommand({ping:1}); db.getSiblingDB("'"${MONGO_DATABASE}"'").getCollectionNames().slice(0,5)' \ 2>/dev/null; then success "MongoDB 连接正常 ✓" else error "MongoDB 连接失败!请检查 .env.deploy-test 中的配置" echo "" echo " 排查步骤:" echo " 1. 确认 MongoDB 服务器 ${MONGO_HOST} 可从本机访问" echo " 2. 确认端口 ${MONGO_PORT} 已开放防火墙" echo " 3. 确认用户名/密码/authSource 正确" echo " 4. 手动测试: mongosh \"$MONGO_URI\"" fi # 方法2:nc 端口连通 elif command -v nc &>/dev/null; then info "mongosh 未安装,使用 nc 检查端口..." if nc -z -w5 "${MONGO_HOST}" "${MONGO_PORT}" 2>/dev/null; then success "MongoDB 端口 ${MONGO_HOST}:${MONGO_PORT} 可达 ✓" warn "(未验证认证,安装 mongosh 可做完整测试: $(_hint_install_mongosh))" else error "MongoDB 端口不可达: ${MONGO_HOST}:${MONGO_PORT}" fi # 方法3:Python pymongo elif command -v python3 &>/dev/null && python3 -c "import pymongo" 2>/dev/null; then info "使用 Python pymongo 验证..." python3 - < [endpoint] _check_s3_bucket() { local label="$1" key_id="$2" secret_key="$3" region="$4" bucket="$5" endpoint="${6:-}" echo -e " Bucket: ${bucket}" echo -e " Region: ${region}" echo -e " AccessKey: ${key_id}" [[ -n "$endpoint" ]] && echo -e " Endpoint: ${endpoint}" echo "" if [[ "${key_id}" == "YOUR_"* || -z "${key_id}" ]]; then error "AccessKeyID 未配置,请编辑 .env.deploy-test" return 1 fi if command -v aws &>/dev/null; then info "使用 awscli 验证..." local endpoint_arg="" [[ -n "$endpoint" ]] && endpoint_arg="--endpoint-url $endpoint" # 用 head-bucket 判成功/失败,避免 `aws s3 ls | head` 因 SIGPIPE 误判失败 local hb_err rc=0 hb_err=$( AWS_ACCESS_KEY_ID="$key_id" \ AWS_SECRET_ACCESS_KEY="$secret_key" \ AWS_DEFAULT_REGION="$region" \ aws s3api head-bucket --bucket "$bucket" $endpoint_arg 2>&1 ) || rc=$? if [[ $rc -eq 0 ]]; then success "S3 Bucket 可访问 ✓(HeadBucket)" local preview preview=$( AWS_ACCESS_KEY_ID="$key_id" \ AWS_SECRET_ACCESS_KEY="$secret_key" \ AWS_DEFAULT_REGION="$region" \ aws s3 ls "s3://${bucket}" $endpoint_arg 2>&1 | head -5 ) || true [[ -n "$preview" ]] && echo "$preview" | sed 's/^/ /' || echo " (列举预览为空)" else error "S3 访问失败!错误: $hb_err" echo " 排查: 确认 AccessKey/SecretKey、Bucket 与 Region、IAM(含 s3:ListBucket / HeadBucket);InvalidAccessKeyId 表示密钥无效或已删除" fi # 测试写入 info "测试写入权限..." local test_key="local-dev-test-$(date +%s)" local write_ok=false AWS_ACCESS_KEY_ID="$key_id" \ AWS_SECRET_ACCESS_KEY="$secret_key" \ AWS_DEFAULT_REGION="$region" \ aws s3 cp /dev/stdin "s3://${bucket}/${test_key}" \ $endpoint_arg --content-type text/plain \ <<< "local-dev-test" 2>/dev/null && write_ok=true || true if $write_ok; then AWS_ACCESS_KEY_ID="$key_id" AWS_SECRET_ACCESS_KEY="$secret_key" \ AWS_DEFAULT_REGION="$region" \ aws s3 rm "s3://${bucket}/${test_key}" $endpoint_arg 2>/dev/null || true success "S3 写入权限正常 ✓" else warn "S3 写入测试失败(Bucket 可读但可能无写权限)" fi else warn "awscli 未安装,跳过验证($(_hint_install_awscli))" echo " 手动验证: AWS_ACCESS_KEY_ID=${key_id} aws s3 ls s3://${bucket}" fi } check_s3() { _try_install_awscli step "MinIO (open-im-server) — IM 文件存储(Docker dev-minio)" _check_s3_bucket \ "openim" \ "${MINIO_ROOT_USER}" \ "${MINIO_ROOT_PASSWORD}" \ "us-east-1" \ "${MINIO_BUCKET}" \ "http://127.0.0.1:${MINIO_API_PORT:-9000}" echo "" step "S3 (build-server) — App APK/IPA 构建产物" _check_s3_bucket \ "build" \ "${BUILD_AWS_ACCESS_KEY}" \ "${BUILD_AWS_SECRET_KEY}" \ "${BUILD_AWS_REGION}" \ "${BUILD_AWS_BUCKET}" } # ────────────────────────────────────────────────────────────────────────────── # 入口 # ────────────────────────────────────────────────────────────────────────────── case "$TARGET" in all) check_mongo; echo ""; check_s3 ;; mongo) check_mongo ;; s3) check_s3 ;; *) error "未知参数: $TARGET" echo "用法: $0 [all|mongo|s3]" exit 1 ;; esac echo ""