#!/bin/bash set -e set -o pipefail # ================= 颜色与日志 ================= RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' 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"; } # ================= 参数检查 ================= if [ -z "$1" ] || [ -z "$2" ]; then echo "========================================" log_error "缺少参数!" echo "用法: $0 <用户@主机名> <设备1,设备2,设备3,设备4>" echo "示例: $0 zhengyu@minio1 '/dev/sdb,/dev/sdc,/dev/sdd,/dev/sde'" echo "注意:设备之间用逗号分隔,不要有空格" echo "========================================" exit 1 fi TARGET_NODE="$1" # 将逗号分隔的字符串转换为数组 IFS=',' read -r -a DEVICES <<< "$2" FILESYSTEM="xfs" # ================= 辅助函数 ================= run_ssh() { local NODE=$1 local CMD=$2 if ! ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o LogLevel=ERROR "${NODE}" "$CMD"; then log_error "SSH 执行失败: ${CMD}" return 1 fi } # ================= 核心逻辑 ================= prepare_disks_on_node() { local NODE=$1 log_step " 正在节点 ${NODE} 上准备磁盘..." if [ ${#DEVICES[@]} -ne 4 ]; then log_error "❌ 配置错误:必须提供 4 个设备,当前数量: ${#DEVICES[@]}" return 1 fi for i in "${!DEVICES[@]}"; do local DEV="${DEVICES[$i]}" local DRIVE_IDX=$((i + 1)) local MOUNT_POINT="/mnt/drive${DRIVE_IDX}" local LABEL_NAME="DATA${DRIVE_IDX}" log_info " -> 处理设备: ${DEV} (挂载点: ${MOUNT_POINT})" # 1. 检查设备是否存在 if ! run_ssh "${NODE}" "test -b ${DEV}"; then log_error " ❌ 设备 ${DEV} 不存在,请检查硬件或路径。" return 1 fi # 2. 强制格式化 (高危) log_warn " ⚠️ 正在格式化 ${DEV} (数据将丢失)..." if ! run_ssh "${NODE}" "sudo mkfs.${FILESYSTEM} -f -L ${LABEL_NAME} ${DEV}"; then log_error " ❌ 格式化失败: ${DEV}" return 1 fi # 3. 创建挂载点 run_ssh "${NODE}" "sudo mkdir -p ${MOUNT_POINT}" # 4. 更新 /etc/fstab log_info " 配置 /etc/fstab..." run_ssh "${NODE}" "sudo cp /etc/fstab /etc/fstab.bak.\$(date +%F)" # 清理可能存在的旧记录 (防止重复) run_ssh "${NODE}" "sudo sed -i '/${LABEL_NAME}/d' /etc/fstab" run_ssh "${NODE}" "sudo sed -i '\\|${MOUNT_POINT}|d' /etc/fstab" # 写入新记录 run_ssh "${NODE}" "echo 'LABEL=${LABEL_NAME} ${MOUNT_POINT} ${FILESYSTEM} defaults 0 2' | sudo tee -a /etc/fstab" # 5. 挂载 log_info " ⛰️ 执行挂载..." if ! run_ssh "${NODE}" "sudo mount -a"; then log_error " ❌ 挂载失败 (mount -a),请检查 fstab 语法。" return 1 fi # 6. 验证 if run_ssh "${NODE}" "mountpoint -q ${MOUNT_POINT}"; then log_info " ✅ ${DEV} 成功挂载到 ${MOUNT_POINT}" else log_error " ❌ 验证失败: ${MOUNT_POINT} 未挂载" return 1 fi # 7. 创建基础目录结构 (此时还没有 minio 用户,先属主 root,稍后 deploy 脚本会 chown) run_ssh "${NODE}" "sudo chmod 755 ${MOUNT_POINT}" done log_info "✅ 节点 ${NODE} 磁盘准备完成" } # ================= 主流程 ================= echo "========================================" log_step " 磁盘初始化脚本" log_info " 目标节点: ${TARGET_NODE}" log_info " 目标设备: ${DEVICES[*]}" echo "========================================" log_warn "⚠️ 高危警告:即将格式化以下设备,数据不可恢复!" for dev in "${DEVICES[@]}"; do log_warn " - $dev"; done echo "" if [ -t 0 ]; then read -p "确认格式化?(输入 y): " confirm if [ "$confirm" != "y" ]; then log_info "❌ 操作取消。" exit 0 fi else log_warn "⚠️ 非交互模式,自动继续..." fi if prepare_disks_on_node "${TARGET_NODE}"; then echo "========================================" log_info " 磁盘初始化成功!" log_info " 下一步请运行: ./3.deploy_cluster.sh ${TARGET_NODE}" echo "========================================" else log_error " 磁盘初始化失败!" exit 1 fi