first commit

This commit is contained in:
root
2026-04-26 13:25:50 +08:00
commit 6e46c06edd
20 changed files with 17274 additions and 0 deletions

254
pkgs/ks/dfmt.sh Normal file
View 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