服务器扩容硬盘后创建LVM自动化脚本

#!/bin/bash
# Author: Cuicui
# Created: 2023/05/05
# Description: 磁盘分区及LVM管理脚本
# Version: 2.0
# Contact: 12312345678

#################### 初始化设置 ####################
set -euo pipefail
trap 'echo -e "\033[31m错误发生在第${LINENO}行,命令: $BASH_COMMAND\033[0m"' ERR

RED='\033[31m'
GREEN='\033[32m'
YELLOW='\033[33m'
NC='\033[0m'

#################### 函数定义 ####################
# 输入验证函数
validate_input() {
    local value=$1
    local pattern=$2
    local err_msg=$3
    
    if [[ ! $value =~ $pattern ]]; then
        echo -e "${RED}错误:${err_msg}${NC}"
        exit 1
    fi
}

# 检查设备是否存在
check_device() {
    local device=$1
    if [[ ! -b $device ]]; then
        echo -e "${RED}错误:设备 ${device} 不存在${NC}"
        exit 1
    fi
}

#################### 第一部分:准备工作 ####################
echo -e "${GREEN}======= 开始磁盘分区及LVM配置 =======${NC}"

# 获取挂载点并创建目录
while true; do
    read -rp "请输入LVM挂载目录 (例如 /data): " data_dir
    validate_input "$data_dir" '^/.*[^/]$' "挂载点格式不正确"
    
    if [ ! -d "$data_dir" ]; then
        if mkdir -p "$data_dir"; then
            echo -e "${GREEN}目录创建成功: ${data_dir}${NC}"
            break
        else
            echo -e "${RED}目录创建失败,请检查权限${NC}"
        fi
    else
        echo -e "${YELLOW}目录已存在: ${data_dir}${NC}"
        break
    fi
done

# 显示当前存储设备
echo -e "\n${GREEN}当前存储设备列表:${NC}"
lsblk -o NAME,SIZE,TYPE,MOUNTPOINT,FSTYPE

#################### 第二部分:磁盘分区 ####################
while true; do
    read -rp "请输入需要分区的设备 (例如 /dev/sdb): " disk_name
    validate_input "$disk_name" '^/dev/[a-z]+$' "设备名称格式不正确"
    check_device "$disk_name"

    # 检查现有分区
    if parted -s "$disk_name" print | grep -q '^ [0-9]'; then
        echo -e "${YELLOW}警告:该设备已有分区!${NC}"
        read -rp "是否继续操作?这将清除所有现有数据![y/N]: " confirm
        if [[ ! $confirm =~ ^[Yy] ]]; then
            echo "操作已取消"
            exit 0
        fi
    fi

    # 执行分区操作
    if parted -s "$disk_name" mklabel gpt && \
       parted -s "$disk_name" mkpart primary 0% 100% && \
       parted -s "$disk_name" set 1 lvm on; then
        echo -e "${GREEN}分区创建成功${NC}"
        partprobe "$disk_name"
        sleep 2
        break
    else
        echo -e "${RED}分区操作失败,请检查设备状态${NC}"
    fi
done

#################### 第三部分:LVM配置 ####################
partition="${disk_name}1"
check_device "$partition"

# 创建物理卷
if ! pvdisplay "$partition" &>/dev/null; then
    pvcreate -y "$partition"
    echo -e "${GREEN}物理卷创建成功: ${partition}${NC}"
else
    echo -e "${YELLOW}物理卷已存在: ${partition}${NC}"
fi

# 创建卷组
while true; do
    read -rp "请输入卷组名称 (例如 vg00): " vg_name
    validate_input "$vg_name" '^[a-z0-9]+$' "卷组名称只能包含小写字母和数字"
    
    if vgdisplay "$vg_name" &>/dev/null; then
        echo -e "${YELLOW}卷组已存在: ${vg_name}${NC}"
        read -rp "是否使用现有卷组?[Y/n]: " use_existing
        [[ $use_existing =~ ^[Nn] ]] || break
    else
        vgcreate "$vg_name" "$partition" && break
    fi
done

# 创建逻辑卷
while true; do
    read -rp "请输入逻辑卷名称 (例如 lv00): " lv_name
    validate_input "$lv_name" '^[a-z0-9]+$' "逻辑卷名称只能包含小写字母和数字"
    
    lv_path="/dev/${vg_name}/${lv_name}"
    if lvdisplay "$lv_path" &>/dev/null; then
        echo -e "${YELLOW}逻辑卷已存在: ${lv_path}${NC}"
        read -rp "是否重新创建?[y/N]: " recreate
        [[ $recreate =~ ^[Yy] ]] || break
        lvremove -y "$lv_path"
    fi
    
    lvcreate -l 100%FREE -n "$lv_name" "$vg_name" && break
done

#################### 第四部分:文件系统配置 ####################
# 选择文件系统类型
PS3="请选择文件系统类型: "
select filetype in xfs ext4 btrfs; do
    case $filetype in
        xfs|ext4|btrfs) break ;;
        *) echo "无效选择,请重新输入" ;;
    esac
done

# 格式化逻辑卷
mkfs_cmd="mkfs.$filetype"
if ! $mkfs_cmd "$lv_path"; then
    echo -e "${RED}格式化失败,请检查参数${NC}"
    exit 1
fi

# 更新fstab并挂载
fstab_entry="$lv_path $data_dir $filetype defaults 0 0"
if grep -qF "$lv_path" /etc/fstab; then
    echo -e "${YELLOW}fstab中已存在该设备记录${NC}"
else
    echo "$fstab_entry" >> /etc/fstab
    echo -e "${GREEN}已更新fstab配置${NC}"
fi

mount -av
echo -e "\n${GREEN}最终存储配置:${NC}"
lsblk -o NAME,SIZE,FSTYPE,MOUNTPOINT

#################### 脚本结束 ####################
echo -e "\n${GREEN}======= 操作成功完成 =======${NC}"

你可能感兴趣的:(服务器,自动化,shell,运维,linux,学习)