336 lines
13 KiB
Bash
Executable File
336 lines
13 KiB
Bash
Executable File
#!/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 - <<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 / 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 ""
|