#!/usr/bin/env bash # ============================================================================= # check-conn.sh — 验证远程服务连接(MongoDB 和 Amazon S3) # # 用法: # ./check-conn.sh # 同时检查 MongoDB 和 S3 # ./check-conn.sh mongo # 只检查 MongoDB # ./check-conn.sh s3 # 只检查 S3 # ============================================================================= set -euo pipefail source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/common.sh" load_env init_script_log # ← 脚本执行日志 TARGET="${1:-all}" header "远程服务连接检查" # ────────────────────────────────────────────────────────────────────────────── # MongoDB # ────────────────────────────────────────────────────────────────────────────── check_mongo() { 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.local 中的配置" 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 可做完整测试)" 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 "S3 AccessKeyID 未配置,请编辑 .env.local" return 1 fi if command -v aws &>/dev/null; then info "使用 awscli 验证..." local endpoint_arg="" [[ -n "$endpoint" ]] && endpoint_arg="--endpoint-url $endpoint" local result rc=0 result=$( 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 ) || rc=$? if [[ $rc -eq 0 ]]; then success "S3 Bucket 可访问 ✓" [[ -n "$result" ]] && echo "$result" | sed 's/^/ /' || echo " (Bucket 为空)" else error "S3 访问失败!错误: $result" echo " 排查: 确认 AccessKey/SecretKey、Bucket 名称、IAM s3:ListBucket 权限" 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 未安装,跳过验证(brew install awscli)" echo " 手动验证: AWS_ACCESS_KEY_ID=${key_id} aws s3 ls s3://${bucket}" fi } check_s3() { step "S3 (open-im-server) — IM 文件存储" _check_s3_bucket \ "openim" \ "${OPENIM_AWS_ACCESS_KEY_ID}" \ "${OPENIM_AWS_SECRET_ACCESS_KEY}" \ "${OPENIM_AWS_REGION}" \ "${OPENIM_AWS_BUCKET}" \ "${OPENIM_AWS_ENDPOINT:-}" 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 ""