first commit
This commit is contained in:
254
pkgs/ks/dfmt.sh
Normal file
254
pkgs/ks/dfmt.sh
Normal file
@@ -0,0 +1,254 @@
|
||||
#!/bin/bash
|
||||
|
||||
get_disk_priority() {
|
||||
local disk=$1
|
||||
local disk_name=$(basename $disk)
|
||||
|
||||
if [[ $disk_name == nvme* ]]; then
|
||||
echo 1
|
||||
return
|
||||
fi
|
||||
|
||||
local rotational=$(cat /sys/block/$disk/queue/rotational 2>/dev/null)
|
||||
if [[ $rotational -eq 0 ]]; then
|
||||
echo 2
|
||||
return
|
||||
fi
|
||||
|
||||
local transport=$(lsblk -d -o NAME,TRAN /dev/$disk 2>/dev/null | grep $disk | awk '{print $2}')
|
||||
if [[ $transport == "sas" ]]; then
|
||||
echo 3
|
||||
else
|
||||
echo 4 # SATA OR OTHER
|
||||
fi
|
||||
}
|
||||
|
||||
get_disk_size() {
|
||||
local disk=$1
|
||||
cat /sys/block/$disk/size 2>/dev/null
|
||||
}
|
||||
|
||||
is_installed_node() {
|
||||
local disks=$(lsblk -d -n -o NAME,TYPE | grep disk | awk '{print $1}')
|
||||
|
||||
for disk in $disks; do
|
||||
local partitions=$(lsblk -n -o NAME /dev/$disk | grep -E "^${disk}p?[0-9]+" || true)
|
||||
|
||||
for part in $partitions; do
|
||||
local mount_point="/mnt/tmp_${part}"
|
||||
mkdir -p $mount_point 2>/dev/null
|
||||
|
||||
if mount -t ext4 -o ro /dev/$part $mount_point 2>/dev/null || \
|
||||
mount -t xfs -o ro /dev/$part $mount_point 2>/dev/null; then
|
||||
|
||||
if [[ -f $mount_point/.sunhpc-release ]]; then
|
||||
umount $mount_point
|
||||
rmdir $mount_point 2>/dev/null
|
||||
echo "yes"
|
||||
return 0
|
||||
fi
|
||||
umount $mount_point
|
||||
fi
|
||||
rmdir $mount_point 2>/dev/null
|
||||
done
|
||||
done
|
||||
|
||||
echo "no"
|
||||
}
|
||||
|
||||
select_best_disk() {
|
||||
local disks=()
|
||||
|
||||
for disk in /sys/block/*; do
|
||||
local disk_name=$(basename $disk)
|
||||
if [[ $disk_name =~ ^(loop|zram|ram|sr|fd|dm-) ]]; then
|
||||
continue
|
||||
fi
|
||||
if [[ -e /dev/$disk_name ]] && [[ $(cat /sys/block/$disk_name/removable 2>/dev/null) -eq 0 ]]; then
|
||||
disks+=($disk_name)
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ ${#disks[@]} -eq 0 ]]; then
|
||||
echo ""
|
||||
return 1
|
||||
fi
|
||||
|
||||
declare -A disk_priority
|
||||
declare -A disk_size
|
||||
|
||||
for disk in "${disks[@]}"; do
|
||||
disk_priority[$disk]=$(get_disk_priority $disk)
|
||||
disk_size[$disk]=$(get_disk_size $disk)
|
||||
done
|
||||
|
||||
local sorted_disks=($(for disk in "${disks[@]}"; do
|
||||
echo "${disk_priority[$disk]}:${disk_size[$disk]}:$disk"
|
||||
done | sort -n -t: -k1,1 -k2,2rn | cut -d: -f3))
|
||||
|
||||
echo "${sorted_disks[0]}"
|
||||
}
|
||||
|
||||
# 智能计算 Root 分区大小
|
||||
# 参数: $1 = 磁盘总大小(GB), $2 = 期望的默认大小(GB)
|
||||
# 返回: 合适的 root 分区大小(GB)
|
||||
calculate_root_size() {
|
||||
local disk_total_gb=$1
|
||||
local default_root_gb=${2:-70}
|
||||
local min_root_gb=30
|
||||
local max_root_gb=100
|
||||
|
||||
# 如果磁盘总容量小于最小要求(70GB + boot + swap = 约75GB)
|
||||
if [[ $disk_total_gb -lt 75 ]]; then
|
||||
# 磁盘太小,使用最小 root 分区
|
||||
echo $min_root_gb
|
||||
elif [[ $disk_total_gb -lt 100 ]]; then
|
||||
# 磁盘在 75-100GB 之间,使用 40-50GB
|
||||
echo $((disk_total_gb - 45)) # 预留 boot+swap+state 空间
|
||||
elif [[ $disk_total_gb -lt 150 ]]; then
|
||||
# 磁盘在 100-150GB 之间,使用 60GB
|
||||
echo 60
|
||||
elif [[ $disk_total_gb -lt 250 ]]; then
|
||||
# 磁盘在 150-250GB 之间,使用默认 70GB
|
||||
echo $default_root_gb
|
||||
else
|
||||
# 大磁盘,限制最大 100GB
|
||||
echo $max_root_gb
|
||||
fi
|
||||
}
|
||||
|
||||
calculate_state_size() {
|
||||
local disk_total_sectors=$1
|
||||
local root_size_sectors=$2
|
||||
echo $((disk_total_sectors - root_size_sectors))
|
||||
}
|
||||
|
||||
get_disk_size_gb() {
|
||||
local disk=$1
|
||||
local total_sectors=$(cat /sys/block/$disk/size 2>/dev/null)
|
||||
local total_gb=$((total_sectors * 512 / 1024 / 1024 / 1024))
|
||||
echo $total_gb
|
||||
}
|
||||
|
||||
get_disk_type() {
|
||||
local disk=$1
|
||||
|
||||
if [[ $disk == nvme* ]]; then
|
||||
echo "NVMe"
|
||||
elif [[ $(cat /sys/block/$disk/queue/rotational 2>/dev/null) -eq 0 ]]; then
|
||||
echo "SSD"
|
||||
else
|
||||
local transport=$(lsblk -d -o NAME,TRAN /dev/$disk 2>/dev/null | grep $disk | awk '{print $2}')
|
||||
if [[ $transport == "sas" ]]; then
|
||||
echo "SAS"
|
||||
else
|
||||
echo "SATA"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
generate_ks_partition() {
|
||||
local disk=$1
|
||||
local is_upgrade=$2
|
||||
|
||||
# 获取磁盘总容量(扇区和GB)
|
||||
local total_sectors=$(cat /sys/block/$disk/size)
|
||||
local total_gb=$(get_disk_size_gb $disk)
|
||||
local disk_type=$(get_disk_type $disk)
|
||||
|
||||
# 智能计算 root 分区大小
|
||||
local root_gb=$(calculate_root_size $total_gb 70)
|
||||
local root_size_sectors=$((root_gb * 1024 * 1024 * 1024 / 512))
|
||||
|
||||
# 计算剩余空间给 state 分区
|
||||
local remaining_sectors=$((total_sectors - root_size_sectors))
|
||||
local remaining_gb=$((remaining_sectors * 512 / 1024 / 1024 / 1024))
|
||||
|
||||
# 计算 boot 和 swap 预留空间
|
||||
local boot_gb=1
|
||||
local swap_gb=4
|
||||
local reserved_gb=$((boot_gb + swap_gb))
|
||||
|
||||
cat << EOF
|
||||
# ==================================================
|
||||
# Disk Partition Information
|
||||
# ==================================================
|
||||
# Installation Type : $([ "$is_upgrade" == "yes" ] && echo "Upgrade" || echo "Fresh") Installation
|
||||
# Disk Device : /dev/$disk
|
||||
# Disk Type : $disk_type
|
||||
# Disk Total : $total_gb GB ($total_sectors sectors)
|
||||
#
|
||||
# Partition Plan:
|
||||
# - /boot : ${boot_gb}GB (reserved)
|
||||
# - swap : ${swap_gb}GB (reserved)
|
||||
# - / : ${root_gb}GB ($root_size_sectors sectors)
|
||||
# - /state : ${remaining_gb}GB ($remaining_sectors sectors)
|
||||
# ==================================================
|
||||
EOF
|
||||
|
||||
cat << EOF
|
||||
zerombr
|
||||
ignoredisk --only-use=$disk
|
||||
clearpart --all --initlabel
|
||||
part /boot --fstype="xfs" --size=1024 --ondisk=$disk
|
||||
part swap --fstype="swap" --size=4096 --ondisk=$disk
|
||||
part / --fstype="xfs" --size=$((root_gb * 1024)) --ondisk=$disk
|
||||
EOF
|
||||
|
||||
if [[ $is_upgrade == "yes" ]]; then
|
||||
cat << EOF
|
||||
part /state/partition1 --fstype=xfs --size=1 --grow --ondisk=$disk
|
||||
EOF
|
||||
fi
|
||||
}
|
||||
|
||||
main() {
|
||||
local is_installed=$(is_installed_node)
|
||||
|
||||
if [[ $is_installed == "yes" ]]; then
|
||||
echo "# Detected: Already installed node (found .sunhpc-release)"
|
||||
local found_disk=""
|
||||
local disks=$(lsblk -d -n -o NAME,TYPE | grep disk | awk '{print $1}')
|
||||
|
||||
for disk in $disks; do
|
||||
local partitions=$(lsblk -n -o NAME /dev/$disk | grep -E "^${disk}p?[0-9]+" || true)
|
||||
for part in $partitions; do
|
||||
local mount_point="/mnt/tmp_${part}"
|
||||
mkdir -p $mount_point 2>/dev/null
|
||||
if mount -t ext4 -o ro /dev/$part $mount_point 2>/dev/null || \
|
||||
mount -t xfs -o ro /dev/$part $mount_point 2>/dev/null; then
|
||||
if [[ -f $mount_point/.sunhpc-release ]]; then
|
||||
found_disk=$disk
|
||||
umount $mount_point
|
||||
rmdir $mount_point 2>/dev/null
|
||||
break 2
|
||||
fi
|
||||
umount $mount_point
|
||||
fi
|
||||
rmdir $mount_point 2>/dev/null
|
||||
done
|
||||
done
|
||||
|
||||
if [[ -n $found_disk ]]; then
|
||||
echo "# Found existing installation on disk: /dev/$found_disk"
|
||||
generate_ks_partition $found_disk "yes"
|
||||
else
|
||||
echo "# ERROR: Cannot find disk with .sunhpc-release, using default"
|
||||
local best_disk=$(select_best_disk)
|
||||
generate_ks_partition $best_disk "yes"
|
||||
fi
|
||||
else
|
||||
echo "# Detected: Fresh installation"
|
||||
local best_disk=$(select_best_disk)
|
||||
|
||||
if [[ -z $best_disk ]]; then
|
||||
echo "# ERROR: No disk found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "# Selected best disk: /dev/$best_disk"
|
||||
generate_ks_partition $best_disk "no"
|
||||
fi
|
||||
}
|
||||
|
||||
main
|
||||
Reference in New Issue
Block a user