#!/bin/bash # ================= 1. 全局设置 ================= set -e set -o pipefail set -u # ================= 2. 颜色与日志函数定义 ================= RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' CYAN='\033[0;36m' NC='\033[0m' # No Color log_info() { echo -e "${GREEN}[INFO]${NC} $1"; } log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } log_error() { echo -e "${RED}[ERROR]${NC} $1"; } log_step() { echo -e "${BLUE}[STEP]${NC} $1"; } log_success() { echo -e "${CYAN}[OK]${NC} $1"; } # 检查并安装sshpass|jq for pkg in sshpass jq; do if ! command -v $pkg &> /dev/null; then log_warn "未找到 $pkg,正在安装..." if command -v apt &> /dev/null; then sudo apt update >/dev/null 2>&1 && sudo apt install -y $pkg >/dev/null 2>&1 elif command -v yum &> /dev/null; then sudo yum install -y $pkg >/dev/null 2>&1 elif command -v dnf &> /dev/null; then sudo dnf install -y $pkg >/dev/null 2>&1 else log_error "请手动安装 $pkg" exit 1 fi log_success "$pkg 安装完成" fi done # ================= 3. 核心函数定义 ================= # 函数:获取远程文件的 SHA256 值 get_remote_sha256() { local SUM_URL=$1 local SUM_FILE=$(basename "$SUM_URL") local TEMP_SUM="/tmp/${SUM_FILE}.$$" # 使用进程ID避免冲突 # 下载校验和文件 (静默) if ! curl -sL -o "$TEMP_SUM" "$SUM_URL" 2>/dev/null; then log_error "无法下载校验和文件: $SUM_URL" rm -f "$TEMP_SUM" return 1 fi # 提取哈希值 local HASH=$(awk '{print $1}' "$TEMP_SUM") rm -f "$TEMP_SUM" if [ -z "$HASH" ]; then log_error "无法从校验和文件中解析哈希值" return 1 fi echo "$HASH" } # 函数:智能下载并校验 download_and_verify() { local BIN_URL=$1 local SUM_URL=$2 local FILENAME=$3 log_step " 正在检查 ${FILENAME} 的完整性..." # 1. 获取远程正确的 SHA256 local REMOTE_SHA REMOTE_SHA=$(get_remote_sha256 "$SUM_URL") local GET_HASH_STATUS=$? if [ $GET_HASH_STATUS -ne 0 ] || [ -z "$REMOTE_SHA" ]; then log_warn "⚠️ 无法获取远程哈希,将跳过版本比对,强制重新下载 ${FILENAME}..." REMOTE_SHA="" else log_info " 远程版本哈希: ${REMOTE_SHA:0:16}..." fi # 2. 检查本地文件是否存在且匹配 local NEED_DOWNLOAD=true if [ -f "$FILENAME" ]; then local LOCAL_SHA=$(sha256sum "$FILENAME" | awk '{print $1}') log_info " 本地版本哈希: ${LOCAL_SHA:0:16}..." if [ -n "$REMOTE_SHA" ] && [ "$LOCAL_SHA" == "$REMOTE_SHA" ]; then log_info "✅ ${FILENAME} 校验通过,无需下载。" NEED_DOWNLOAD=false else if [ -z "$REMOTE_SHA" ]; then log_warn "⚠️ ${FILENAME} 存在但无法验证远程版本,为确保一致性,准备更新..." else log_warn "⚠️ ${FILENAME} 哈希不匹配,准备更新..." fi fi else log_info " 本地文件不存在。" fi # 3. 如果需要下载 if [ "$NEED_DOWNLOAD" == true ]; then log_info " 正在下载 ${FILENAME} ..." # 使用 curl 下载,显示进度条 (-#), 跟随重定向 (-L) if ! curl -L# -o "$FILENAME" "$BIN_URL"; then log_error "❌ 下载 ${FILENAME} 失败!" rm -f "$FILENAME" # 清理可能损坏的部分文件 exit 1 fi # 4. 下载后再次校验 log_info " 正在校验下载文件的完整性..." local NEW_LOCAL_SHA=$(sha256sum "$FILENAME" | awk '{print $1}') if [ -n "$REMOTE_SHA" ] && [ "$NEW_LOCAL_SHA" != "$REMOTE_SHA" ]; then log_error "❌ 下载后的文件哈希校验失败!" log_error " 期望: $REMOTE_SHA" log_error " 实际: $NEW_LOCAL_SHA" log_error " 文件可能已损坏或被篡改,删除临时文件并退出。" rm -f "$FILENAME" exit 1 else log_info "✅ ${FILENAME} 下载成功且校验通过!" chmod +x "$FILENAME" log_info " 已添加执行权限。" fi fi } # ================= 4. 主执行流程 ================= echo "========================================" log_step " 阶段 0: 准备本地二进制文件" echo "========================================" # 官方的下载文件 #MINIO_URL="https://dl.min.io/server/minio/release/linux-amd64/minio" #MINIO_SUM_URL="https://dl.min.io/server/minio/release/linux-amd64/minio.sha256sum" #MC_URL="https://dl.min.io/client/mc/release/linux-amd64/mc" #MC_SUM_URL="https://dl.min.io/client/mc/release/linux-amd64/mc.sha256sum" #JUICEFS_URL="https://github.com/juicedata/juicefs/releases/download/v1.3.1/juicefs-1.3.1-linux-amd64.tar.gz" # 定义资源 MINIO_BIN="minio" MINIO_BIN_URL="https://zhengyu1992.cn/file/software/magiclab/minio/minio" MINIO_SUM_URL="https://zhengyu1992.cn/file/software/magiclab/minio/minio.sha256sum" MC_BIN="mc" MC_BIN_URL="https://zhengyu1992.cn/file/software/magiclab/minio/mc" MC_SUM_URL="https://zhengyu1992.cn/file/software/magiclab/minio/mc.sha256sum" JUICEFS_BIN="juicefs" JUICEFS_BIN_URL="https://zhengyu1992.cn/file/software/magiclab/juicefs/juicefs" JUICEFS_SUM_URL="https://zhengyu1992.cn/file/software/magiclab/juicefs/juicefs.sha256sum" # 下载资源 download_and_verify "$MINIO_BIN_URL" "$MINIO_SUM_URL" "$MINIO_BIN" download_and_verify "$MC_BIN_URL" "$MC_SUM_URL" "$MC_BIN" cp "$MC_BIN" /usr/local/bin/ # 下载juicefs download_and_verify "$JUICEFS_BIN_URL" "$JUICEFS_SUM_URL" "$JUICEFS_BIN" cp "$JUICEFS_BIN" /usr/local/bin/ echo "========================================" log_info " 本地文件准备就绪!" log_info " - 二进制文件: minio, mc, juicefs" echo "========================================" loginfo " 下载其他资源和安装子脚本" log_info " - 脚本文件: 1.deploy_keys.sh, 1.1.deploy_keys_single.sh" echo "========================================" curl -s -S -f -o "host_list-example.txt" "https://zhengyu1992.cn/file/software/magiclab/host_list-example.txt" log_info " - 请参照host_list-example.txt配置minio,redis,juicefs主机配置文件并重命名为host_list.txt " curl -s -S -f -o ".env.example" "https://zhengyu1992.cn/file/software/magiclab/.env.example" log_info " - 请修改.env.example中minio和redis的账号密码信息,并重命名为.env" exit 0