大量更新

This commit is contained in:
zeaslity
2026-05-19 14:28:44 +08:00
parent a8f6bda703
commit 9fc3372fa3
5299 changed files with 423176 additions and 426690 deletions

View File

@@ -0,0 +1,250 @@
#!/usr/bin/env bash
set -euo pipefail
DISK="/dev/sdb"
PART="${DISK}1"
NEW_VG="docker_vg"
NEW_LV="docker_lv"
MOUNT_POINT="/var/lib/docker"
FS_TYPE="ext4" # 可改 ext4
LV_SIZE="100%FREE"
log() {
echo -e "\n[INFO] $*"
}
warn() {
echo -e "\n[WARN] $*" >&2
}
die() {
echo -e "\n[ERROR] $*" >&2
exit 1
}
require_cmd() {
command -v "$1" >/dev/null 2>&1 || die "缺少命令: $1"
}
cleanup_mounts_on_disk() {
log "检查 ${DISK} 相关挂载点"
mapfile -t mps < <(lsblk -nrpo NAME,MOUNTPOINT "${DISK}" | awk '$2 != "" {print $2}' | sort -u)
if [[ ${#mps[@]} -gt 0 ]]; then
warn "发现 ${DISK} 上存在挂载点: ${mps[*]}"
for mp in "${mps[@]}"; do
if mountpoint -q "$mp"; then
log "卸载挂载点: $mp"
umount -f "$mp" || die "无法卸载 $mp"
fi
done
else
log "未发现 ${DISK} 的活动挂载点"
fi
}
stop_docker() {
log "停止 Docker 相关服务"
systemctl stop docker 2>/dev/null || true
systemctl stop docker.socket 2>/dev/null || true
systemctl stop containerd 2>/dev/null || true
}
deactivate_old_lvm() {
log "检查旧 LVM 信息"
# 尝试识别 /dev/sdb 或 /dev/sdb1 所属 VG
local old_vg=""
old_vg="$(pvs --noheadings -o vg_name "${DISK}" 2>/dev/null | awk '{$1=$1;print}' | head -n1 || true)"
if [[ -z "${old_vg}" && -b "${PART}" ]]; then
old_vg="$(pvs --noheadings -o vg_name "${PART}" 2>/dev/null | awk '{$1=$1;print}' | head -n1 || true)"
fi
if [[ -n "${old_vg}" ]]; then
warn "发现旧 VG: ${old_vg}"
log "列出旧 LV"
lvs --noheadings -o lv_name "${old_vg}" 2>/dev/null | awk '{$1=$1;print}' || true
# 尝试卸载该 VG 下所有 LV 的挂载
while read -r lv; do
[[ -z "${lv}" ]] && continue
local lv_path="/dev/${old_vg}/${lv}"
if [[ -e "${lv_path}" ]]; then
local mp
mp="$(lsblk -nrpo MOUNTPOINT "${lv_path}" 2>/dev/null | awk 'NF{print; exit}' || true)"
if [[ -n "${mp}" && "${mp}" != "[SWAP]" ]]; then
log "卸载 LV 挂载点: ${mp}"
umount -f "${mp}" || true
fi
fi
done < <(lvs --noheadings -o lv_name "${old_vg}" 2>/dev/null | awk '{$1=$1;print}')
log "停用 VG: ${old_vg}"
vgchange -an "${old_vg}" || true
# 再次激活以便删除 LV部分系统需要先处于可见状态
vgchange -ay "${old_vg}" || true
# 删除该 VG 下所有 LV
while read -r lv; do
[[ -z "${lv}" ]] && continue
local lv_path="/dev/${old_vg}/${lv}"
if [[ -e "${lv_path}" ]]; then
log "删除旧 LV: ${lv_path}"
lvremove -ff -y "${lv_path}" || true
fi
done < <(lvs --noheadings -o lv_name "${old_vg}" 2>/dev/null | awk '{$1=$1;print}')
log "停用并删除旧 VG: ${old_vg}"
vgchange -an "${old_vg}" || true
vgremove -ff -y "${old_vg}" || true
else
log "未发现 ${DISK} / ${PART} 上关联的 VG"
fi
# 删除旧 PV
if pvs "${PART}" >/dev/null 2>&1; then
log "删除旧 PV: ${PART}"
pvremove -ff -y "${PART}" || true
fi
if pvs "${DISK}" >/dev/null 2>&1; then
log "删除旧 PV: ${DISK}"
pvremove -ff -y "${DISK}" || true
fi
# 额外清理 device-mapper 残留
log "清理可能遗留的 device-mapper 映射"
dmsetup remove_all 2>/dev/null || true
udevadm settle || true
}
wipe_disk() {
log "清理磁盘签名和分区表: ${DISK}"
swapoff -a 2>/dev/null || true
wipefs -a "${PART}" 2>/dev/null || true
wipefs -a "${DISK}" 2>/dev/null || true
sgdisk --zap-all "${DISK}" || true
dd if=/dev/zero of="${DISK}" bs=1M count=20 conv=fsync status=none || true
sync
partprobe "${DISK}" || true
blockdev --rereadpt "${DISK}" || true
udevadm settle || true
# 如果分区节点还在,尝试删除
if [[ -b "${PART}" ]]; then
warn "${PART} 仍然存在,尝试删除分区表项"
parted -s "${DISK}" rm 1 2>/dev/null || true
partprobe "${DISK}" || true
udevadm settle || true
fi
}
prepare_mountpoint() {
log "准备挂载目录: ${MOUNT_POINT}"
if mountpoint -q "${MOUNT_POINT}"; then
umount -f "${MOUNT_POINT}" || die "无法卸载 ${MOUNT_POINT}"
fi
mkdir -p "${MOUNT_POINT}"
if [[ -n "$(ls -A "${MOUNT_POINT}" 2>/dev/null || true)" ]]; then
local backup_dir="${MOUNT_POINT}.bak.$(date +%F_%H%M%S)"
warn "${MOUNT_POINT} 非空,备份到 ${backup_dir}"
mv "${MOUNT_POINT}" "${backup_dir}"
mkdir -p "${MOUNT_POINT}"
fi
}
create_new_lvm() {
log "在整块磁盘 ${DISK} 上创建新的 LVM"
pvcreate -ff -y "${DISK}"
vgcreate "${NEW_VG}" "${DISK}"
lvcreate -n "${NEW_LV}" -l "${LV_SIZE}" "${NEW_VG}"
local lv_path="/dev/${NEW_VG}/${NEW_LV}"
log "格式化文件系统: ${FS_TYPE}"
if [[ "${FS_TYPE}" == "xfs" ]]; then
mkfs.xfs -f "${lv_path}"
elif [[ "${FS_TYPE}" == "ext4" ]]; then
mkfs.ext4 -F "${lv_path}"
else
die "不支持的文件系统: ${FS_TYPE}"
fi
local uuid
uuid="$(blkid -s UUID -o value "${lv_path}")"
[[ -n "${uuid}" ]] || die "获取 UUID 失败"
log "写入 /etc/fstab"
cp /etc/fstab "/etc/fstab.bak.$(date +%F_%H%M%S)"
sed -i "\|[[:space:]]${MOUNT_POINT}[[:space:]]|d" /etc/fstab
echo "UUID=${uuid} ${MOUNT_POINT} ${FS_TYPE} defaults 0 0" >> /etc/fstab
log "挂载 ${MOUNT_POINT}"
mount -a
log "挂载结果校验"
df -TH "${MOUNT_POINT}"
lsblk
}
start_docker() {
log "启动 Docker"
systemctl daemon-reload
systemctl start containerd 2>/dev/null || true
systemctl start docker
systemctl enable docker 2>/dev/null || true
}
main() {
require_cmd lsblk
require_cmd pvs
require_cmd vgs
require_cmd lvs
require_cmd pvcreate
require_cmd vgcreate
require_cmd lvcreate
require_cmd wipefs
require_cmd sgdisk
require_cmd partprobe
require_cmd blkid
require_cmd dmsetup
require_cmd parted
[[ "$(id -u)" -eq 0 ]] || die "请使用 root 执行"
[[ -b "${DISK}" ]] || die "磁盘不存在: ${DISK}"
echo "======================================================"
echo "即将彻底清空 ${DISK} 并挂载到 ${MOUNT_POINT}"
echo "目标 VG: ${NEW_VG}"
echo "目标 LV: ${NEW_LV}"
echo "文件系统: ${FS_TYPE}"
echo "警告: 此操作会销毁 ${DISK} 上所有数据"
echo "======================================================"
read -r -p "确认执行请输入 YES: " ans
[[ "${ans}" == "YES" ]] || die "用户取消"
stop_docker
cleanup_mounts_on_disk
deactivate_old_lvm
wipe_disk
prepare_mountpoint
create_new_lvm
start_docker
log "完成: ${DISK} -> /dev/${NEW_VG}/${NEW_LV} -> ${MOUNT_POINT}"
}
main "$@"