Files
deploy-test/check-conn.sh
2026-04-13 22:25:56 +07:00

336 lines
13 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/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 # 只检查 MinIOopenim与 S3build
#
# 环境:
# 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-mongoshUbuntu/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"
# 方法1mongosh
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
# 方法2nc 端口连通
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
# 方法3Python pymongo
elif command -v python3 &>/dev/null && python3 -c "import pymongo" 2>/dev/null; then
info "使用 Python pymongo 验证..."
python3 - <<PYEOF
from pymongo import MongoClient
import sys
try:
c = MongoClient("${MONGO_URI}", serverSelectionTimeoutMS=5000)
c.server_info()
print(" MongoDB 连接正常 ✓")
c.close()
except Exception as e:
print(f" 连接失败: {e}", file=sys.stderr)
sys.exit(1)
PYEOF
[[ $? -eq 0 ]] && success "MongoDB 连接正常" || error "MongoDB 连接失败"
else
warn "跳过 MongoDB 连接验证(请安装 mongosh: $(_hint_install_mongosh)"
echo -e " 手动验证: mongosh \"${MONGO_URI}\""
fi
}
# ──────────────────────────────────────────────────────────────────────────────
# Amazon S3
# ──────────────────────────────────────────────────────────────────────────────
# 通用 S3 检查函数
# 用法: _check_s3_bucket <label> <key_id> <secret_key> <region> <bucket> [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 / HeadBucketInvalidAccessKeyId 表示密钥无效或已删除"
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 ""