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
|
||||
753
pkgs/ks/init.sh
Normal file
753
pkgs/ks/init.sh
Normal file
@@ -0,0 +1,753 @@
|
||||
#!/bin/bash
|
||||
# ============================================================================
|
||||
# Sun HPC 系统初始化脚本
|
||||
# 功能:系统安装完成后自动配置 HPC 计算节点环境
|
||||
# 版本:1.0
|
||||
# ============================================================================
|
||||
|
||||
set -e
|
||||
|
||||
# ============================================================================
|
||||
# 配置变量(根据实际环境修改)
|
||||
# ============================================================================
|
||||
|
||||
# 日志文件
|
||||
LOG_FILE="/var/log/sunhpc-init.log"
|
||||
|
||||
FRONTEND_IP="172.16.9.254"
|
||||
|
||||
# HTTP 服务器地址
|
||||
HTTP_SERVER="http://${FRONTEND_IP}"
|
||||
|
||||
# YUM 仓库配置
|
||||
YUM_REPO_NAME="sunhpc-local"
|
||||
YUM_REPO_BASEURL="${HTTP_SERVER}/rocky/9.7"
|
||||
YUM_REPO_GPGCHECK=0
|
||||
|
||||
# 主机名映射文件(在 HTTP 服务器上)
|
||||
HOSTNAME_MAP_URL="${HTTP_SERVER}/ks/hostname-map.txt"
|
||||
|
||||
# MOTD 文件 URL
|
||||
MOTD_URL="${HTTP_SERVER}/ks/motd"
|
||||
|
||||
# NTP 服务器
|
||||
NTP_SERVER="ntp.aliyun.com"
|
||||
|
||||
# DNS 服务器
|
||||
DNS_SERVERS="114.114.114.114 223.5.5.5"
|
||||
|
||||
# ============================================================================
|
||||
# 颜色输出函数
|
||||
# ============================================================================
|
||||
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
log_info() {
|
||||
echo -e "${GREEN}[INFO]${NC} $(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a $LOG_FILE
|
||||
}
|
||||
|
||||
log_warn() {
|
||||
echo -e "${YELLOW}[WARN]${NC} $(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a $LOG_FILE
|
||||
}
|
||||
|
||||
log_error() {
|
||||
echo -e "${RED}[ERROR]${NC} $(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a $LOG_FILE
|
||||
}
|
||||
|
||||
log_step() {
|
||||
echo -e "${BLUE}[STEP]${NC} $(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a $LOG_FILE
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# 基础环境准备
|
||||
# ============================================================================
|
||||
|
||||
init_log() {
|
||||
# 创建日志文件
|
||||
touch $LOG_FILE
|
||||
chmod 644 $LOG_FILE
|
||||
log_info "=========================================="
|
||||
log_info "Sun HPC Node Initialization Started"
|
||||
log_info "=========================================="
|
||||
}
|
||||
|
||||
check_network() {
|
||||
log_step "Checking network connectivity..."
|
||||
|
||||
# 测试网络连接
|
||||
if ping -c 1 -W 3 172.16.9.254 &>/dev/null; then
|
||||
log_info "Network connectivity: OK"
|
||||
return 0
|
||||
else
|
||||
log_warn "Cannot reach HTTP server, will retry later"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# 1. 创建 .sunhpc-release 文件
|
||||
# ============================================================================
|
||||
|
||||
create_release_file() {
|
||||
log_step "Creating .sunhpc-release file..."
|
||||
|
||||
cat > /.sunhpc-release << EOF
|
||||
Sun HPC Platform Release 1.0
|
||||
Build Date: $(date '+%Y-%m-%d %H:%M:%S')
|
||||
Hostname: $(hostname)
|
||||
Kernel: $(uname -r)
|
||||
Architecture: $(uname -m)
|
||||
EOF
|
||||
|
||||
chmod 644 /.sunhpc-release
|
||||
log_info "Created /.sunhpc-release file"
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# 2. 配置主机名和 /etc/hosts
|
||||
# ============================================================================
|
||||
|
||||
configure_hostname() {
|
||||
log_step "Configuring hostname and /etc/hosts..."
|
||||
|
||||
local mac=$(ip link show | grep -oP 'ether \K[0-9a-f:]+' | head -1 | tr '[:upper:]' '[:lower:]')
|
||||
local hostname=""
|
||||
|
||||
# 从 HTTP 服务器获取主机名映射
|
||||
if check_network; then
|
||||
# 下载主机名映射文件
|
||||
local map_file="/tmp/hostname-map.txt"
|
||||
curl -s -o "$map_file" "$HOSTNAME_MAP_URL" 2>/dev/null
|
||||
|
||||
if [[ -f "$map_file" ]]; then
|
||||
# 根据 MAC 地址查找主机名
|
||||
hostname=$(grep -i "$mac" "$map_file" | awk '{print $2}' | head -1)
|
||||
|
||||
# 如果没有找到,根据 IP 最后一段生成
|
||||
if [[ -z "$hostname" ]]; then
|
||||
local ip_addr=$(ip -4 addr show | grep -oP '(?<=inet\s)\d+(\.\d+){3}' | grep -v '127.0.0.1' | head -1)
|
||||
local ip_last=$(echo $ip_addr | awk -F'.' '{print $4}')
|
||||
hostname="cn$(printf "%03d" $ip_last)"
|
||||
log_warn "No hostname mapping for MAC $mac, using generated: $hostname"
|
||||
fi
|
||||
else
|
||||
log_warn "Cannot download hostname map, using default"
|
||||
local ip_addr=$(ip -4 addr show | grep -oP '(?<=inet\s)\d+(\.\d+){3}' | grep -v '127.0.0.1' | head -1)
|
||||
local ip_last=$(echo $ip_addr | awk -F'.' '{print $4}')
|
||||
hostname="cn$(printf "%03d" $ip_last)"
|
||||
fi
|
||||
else
|
||||
# 网络不通时使用默认主机名
|
||||
hostname="node-$(hostname -s)"
|
||||
fi
|
||||
|
||||
# 设置主机名
|
||||
hostnamectl set-hostname "$hostname"
|
||||
log_info "Hostname set to: $hostname"
|
||||
|
||||
# 备份原始 hosts 文件
|
||||
cp /etc/hosts /etc/hosts.bak.$(date +%Y%m%d)
|
||||
|
||||
# 构建新的 hosts 文件
|
||||
cat > /etc/hosts << EOF
|
||||
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
|
||||
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
|
||||
|
||||
# Sun HPC Node Configuration
|
||||
$ip_addr $hostname
|
||||
|
||||
# Management Node
|
||||
$FRONTEND_IP cluster
|
||||
|
||||
# Optional: Add other compute nodes here
|
||||
# 172.16.9.1 cn001
|
||||
# 172.16.9.2 cn002
|
||||
EOF
|
||||
|
||||
# 尝试下载完整的集群 hosts 文件
|
||||
if check_network; then
|
||||
local cluster_hosts="${HTTP_SERVER}/ks/cluster-hosts.txt"
|
||||
if wget --spider -q "$cluster_hosts" 2>/dev/null; then
|
||||
wget -q -O /tmp/cluster-hosts.txt "$cluster_hosts"
|
||||
cat /tmp/cluster-hosts.txt >> /etc/hosts
|
||||
log_info "Downloaded cluster hosts configuration"
|
||||
else
|
||||
log_warn "$cluster_hosts not found on server."
|
||||
fi
|
||||
fi
|
||||
|
||||
log_info "Updated /etc/hosts"
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# 3. 配置 MOTD (Message of The Day)
|
||||
# ============================================================================
|
||||
|
||||
configure_motd() {
|
||||
log_step "Configuring MOTD..."
|
||||
|
||||
# 备份原始 MOTD
|
||||
if [[ -f /etc/motd ]]; then
|
||||
cp /etc/motd /etc/motd.bak.$(date +%Y%m%d)
|
||||
fi
|
||||
|
||||
# 尝试从服务器下载 MOTD
|
||||
if check_network; then
|
||||
if wget --spider -q "$MOTD_URL" 2>/dev/null; then
|
||||
wget -q -O /etc/motd "$MOTD_URL"
|
||||
log_info "Downloaded MOTD from server"
|
||||
else
|
||||
log_warn "Cannot download MOTD, creating default"
|
||||
create_default_motd
|
||||
fi
|
||||
else
|
||||
create_default_motd
|
||||
fi
|
||||
|
||||
chmod 644 /etc/motd
|
||||
}
|
||||
|
||||
create_default_motd() {
|
||||
cat > /etc/motd << EOF
|
||||
===========================================================
|
||||
Sun HPC Platform - Compute Node
|
||||
===========================================================
|
||||
Welcome to Sun High Performance Computing Cluster
|
||||
|
||||
System Information:
|
||||
--------------------
|
||||
Hostname....: $(hostname)
|
||||
IP Address..: $(ip -4 addr show | grep -oP '(?<=inet\s)\d+(\.\d+){3}' | grep -v '127.0.0.1' | head -1)
|
||||
OS Version..: $(cat /etc/redhat-release 2>/dev/null || echo "Rocky Linux")
|
||||
Kernel......: $(uname -r)
|
||||
Architecture: $(uname -m)
|
||||
CPU Cores...: $(nproc)
|
||||
Memory......: $(free -h | awk '/^Mem:/{print $2}')
|
||||
|
||||
Important URLs:
|
||||
--------------------
|
||||
• Documentation : http://172.16.9.254/docs
|
||||
• Job Submission : http://172.16.9.254/slurm
|
||||
• Monitoring: http : http://172.16.9.254/monitor
|
||||
|
||||
Slurm Commands:
|
||||
--------------------
|
||||
sinfo - View partition information
|
||||
squeue - View job queue
|
||||
srun - Run interactive job
|
||||
sbatch - Submit batch job
|
||||
scancel - Cancel job
|
||||
|
||||
===========================================================
|
||||
* Unauthorized access is prohibited
|
||||
* All activities are logged and monitored
|
||||
* For support: hpc@sun.com or ext. 12345
|
||||
===========================================================
|
||||
EOF
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# 4. 配置 YUM 本地仓库
|
||||
# ============================================================================
|
||||
|
||||
configure_yum_repo() {
|
||||
log_step "Configuring YUM repository..."
|
||||
|
||||
local repo_file="/etc/yum.repos.d/${YUM_REPO_NAME}.repo"
|
||||
|
||||
# 备份现有 repo 文件
|
||||
if [[ -f "$repo_file" ]]; then
|
||||
cp "$repo_file" "${repo_file}.bak.$(date +%Y%m%d)"
|
||||
fi
|
||||
|
||||
# 创建仓库配置文件
|
||||
cat > "$repo_file" << EOF
|
||||
[${YUM_REPO_NAME}]
|
||||
name=Sun HPC Local Repository
|
||||
baseurl=${YUM_REPO_BASEURL}
|
||||
enabled=1
|
||||
gpgcheck=${YUM_REPO_GPGCHECK}
|
||||
priority=1
|
||||
EOF
|
||||
|
||||
# 如果是 Rocky 8/9,可能需要配置 appstream
|
||||
if [[ -d "/etc/yum.repos.d" ]]; then
|
||||
local appstream_repo="/etc/yum.repos.d/${YUM_REPO_NAME}-appstream.repo"
|
||||
cat > "$appstream_repo" << EOF
|
||||
[${YUM_REPO_NAME}-appstream]
|
||||
name=Sun HPC Local AppStream Repository
|
||||
baseurl=${YUM_REPO_BASEURL}-appstream
|
||||
enabled=1
|
||||
gpgcheck=${YUM_REPO_GPGCHECK}
|
||||
priority=1
|
||||
EOF
|
||||
fi
|
||||
|
||||
# 清理 YUM 缓存并测试
|
||||
yum clean all &>/dev/null
|
||||
yum makecache &>/dev/null
|
||||
|
||||
if [[ $? -eq 0 ]]; then
|
||||
log_info "YUM repository configured successfully"
|
||||
else
|
||||
log_warn "YUM repository configured but cache generation failed (network may be down)"
|
||||
fi
|
||||
|
||||
# 显示启用的仓库
|
||||
log_info "Enabled repositories:"
|
||||
yum repolist 2>/dev/null | grep -E "^${YUM_REPO_NAME}" | tee -a $LOG_FILE
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# 5. 配置 DNS 解析
|
||||
# ============================================================================
|
||||
|
||||
configure_dns() {
|
||||
log_step "Configuring DNS resolution..."
|
||||
|
||||
# 备份 resolv.conf
|
||||
cp /etc/resolv.conf /etc/resolv.conf.bak.$(date +%Y%m%d) 2>/dev/null || true
|
||||
|
||||
# 配置 DNS
|
||||
cat > /etc/resolv.conf << EOF
|
||||
# Sun HPC DNS Configuration
|
||||
nameserver ${DNS_SERVERS%% *}
|
||||
$(for dns in ${DNS_SERVERS}; do echo "nameserver $dns"; done | tail -n +2)
|
||||
|
||||
# Local domain
|
||||
search sunhpc.local local
|
||||
EOF
|
||||
|
||||
# 防止 NetworkManager 覆盖 resolv.conf
|
||||
if [[ -f /etc/NetworkManager/NetworkManager.conf ]]; then
|
||||
if ! grep -q "dns=none" /etc/NetworkManager/NetworkManager.conf; then
|
||||
sed -i '/^\[main\]/a dns=none' /etc/NetworkManager/NetworkManager.conf
|
||||
systemctl restart NetworkManager 2>/dev/null || true
|
||||
fi
|
||||
fi
|
||||
|
||||
log_info "DNS configured: ${DNS_SERVERS}"
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# 6. 配置 NTP 时间同步
|
||||
# ============================================================================
|
||||
|
||||
configure_ntp() {
|
||||
log_step "Configuring NTP time synchronization..."
|
||||
|
||||
# 使用 chrony (Rocky 8/9 默认)
|
||||
if command -v chronyd &>/dev/null; then
|
||||
# 备份配置
|
||||
cp /etc/chrony.conf /etc/chrony.conf.bak.$(date +%Y%m%d)
|
||||
|
||||
# 配置 chrony
|
||||
cat > /etc/chrony.conf << EOF
|
||||
# Sun HPC NTP Configuration
|
||||
server ${NTP_SERVER} iburst
|
||||
pool 2.rocky.pool.ntp.org iburst
|
||||
|
||||
# Record the rate at which the system clock gains/losses time.
|
||||
driftfile /var/lib/chrony/drift
|
||||
|
||||
# Allow the system clock to be stepped in the first three updates
|
||||
makestep 1.0 3
|
||||
|
||||
# Enable kernel synchronization of the real-time clock (RTC)
|
||||
rtcsync
|
||||
|
||||
# Specify file containing keys for NTP authentication
|
||||
keyfile /etc/chrony.keys
|
||||
|
||||
# Specify directory for log files
|
||||
logdir /var/log/chrony
|
||||
EOF
|
||||
|
||||
# 重启 chrony
|
||||
systemctl restart chronyd &>/dev/null
|
||||
systemctl enable chronyd &>/dev/null
|
||||
|
||||
log_info "Chrony NTP configured with server: ${NTP_SERVER}"
|
||||
else
|
||||
# 使用 ntpd (旧系统)
|
||||
if command -v ntpd &>/dev/null; then
|
||||
cat > /etc/ntp.conf << EOF
|
||||
server ${NTP_SERVER} iburst
|
||||
restrict default nomodify notrap nopeer noquery
|
||||
restrict 127.0.0.1
|
||||
restrict ::1
|
||||
driftfile /var/lib/ntp/drift
|
||||
EOF
|
||||
systemctl restart ntpd &>/dev/null
|
||||
systemctl enable ntpd &>/dev/null
|
||||
log_info "NTP configured with server: ${NTP_SERVER}"
|
||||
else
|
||||
log_warn "No NTP service found (chronyd or ntpd)"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# 7. 配置 SSH 服务
|
||||
# ============================================================================
|
||||
|
||||
configure_ssh() {
|
||||
log_step "Configuring SSH service..."
|
||||
|
||||
# 备份配置
|
||||
cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak.$(date +%Y%m%d)
|
||||
|
||||
# 优化 SSH 配置
|
||||
sed -i 's/#PermitRootLogin.*/PermitRootLogin prohibit-password/' /etc/ssh/sshd_config
|
||||
sed -i 's/#PubkeyAuthentication.*/PubkeyAuthentication yes/' /etc/ssh/sshd_config
|
||||
sed -i 's/#PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config
|
||||
sed -i 's/#UseDNS.*/UseDNS no/' /etc/ssh/sshd_config
|
||||
sed -i 's/#GSSAPIAuthentication.*/GSSAPIAuthentication no/' /etc/ssh/sshd_config
|
||||
|
||||
# 重启 SSH 服务
|
||||
systemctl restart sshd &>/dev/null
|
||||
|
||||
log_info "SSH service configured"
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# 8. 配置防火墙
|
||||
# ============================================================================
|
||||
|
||||
configure_firewall() {
|
||||
log_step "Configuring firewall..."
|
||||
|
||||
# 检查 firewalld 是否运行
|
||||
if systemctl is-active firewalld &>/dev/null; then
|
||||
# 开放常用端口
|
||||
firewall-cmd --permanent --add-service=ssh &>/dev/null
|
||||
firewall-cmd --permanent --add-service=dhcp &>/dev/null
|
||||
firewall-cmd --permanent --add-port=873/tcp &>/dev/null # rsync
|
||||
firewall-cmd --permanent --add-port=111/udp &>/dev/null # rpcbind
|
||||
|
||||
# 重新加载
|
||||
firewall-cmd --reload &>/dev/null
|
||||
|
||||
log_info "Firewall configured"
|
||||
else
|
||||
log_warn "Firewalld not running, skipping configuration"
|
||||
fi
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# 9. 安装常用软件包
|
||||
# ============================================================================
|
||||
|
||||
install_packages() {
|
||||
log_step "Installing common packages..."
|
||||
|
||||
local packages=(
|
||||
wget curl vim nano
|
||||
htop iotop iftop
|
||||
net-tools bind-utils
|
||||
telnet nc tcpdump
|
||||
rsync tree lsof
|
||||
gcc make autoconf automake
|
||||
openssl-devel zlib-devel
|
||||
nfs-utils cifs-utils
|
||||
ntpdate
|
||||
)
|
||||
|
||||
if check_network; then
|
||||
for pkg in "${packages[@]}"; do
|
||||
if rpm -q "$pkg" &>/dev/null; then
|
||||
log_info "Package already installed: $pkg"
|
||||
else
|
||||
log_info "Installing package: $pkg"
|
||||
yum install -y "$pkg" &>> $LOG_FILE || log_warn "Failed to install: $pkg"
|
||||
fi
|
||||
done
|
||||
else
|
||||
log_warn "Network unavailable, skipping package installation"
|
||||
fi
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# 11. 配置用户环境
|
||||
# ============================================================================
|
||||
|
||||
configure_user_env() {
|
||||
log_step "Configuring user environment..."
|
||||
|
||||
# 创建共享目录
|
||||
mkdir -p /share/{apps,home}
|
||||
mkdir -p /state/partition1/{tmp,work}
|
||||
|
||||
# 设置权限
|
||||
chmod 755 /share
|
||||
chmod 1777 /state/partition1/tmp
|
||||
|
||||
# 配置全局环境变量
|
||||
cat > /etc/profile.d/sunhpc.sh << 'EOF'
|
||||
# Sun HPC Environment Variables
|
||||
export SHARE_HOME=/share
|
||||
export STATE_HOME=/state/partition1
|
||||
EOF
|
||||
|
||||
chmod 644 /etc/profile.d/sunhpc.sh
|
||||
log_info "User environment configured"
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# 12. 配置系统优化参数
|
||||
# ============================================================================
|
||||
|
||||
configure_sysctl() {
|
||||
log_step "Configuring system optimization..."
|
||||
|
||||
cat > /etc/sysctl.d/99-sunhpc.conf << EOF
|
||||
# Sun HPC System Optimization
|
||||
|
||||
# Network optimization
|
||||
net.core.rmem_max = 134217728
|
||||
net.core.wmem_max = 134217728
|
||||
net.ipv4.tcp_rmem = 4096 87380 134217728
|
||||
net.ipv4.tcp_wmem = 4096 65536 134217728
|
||||
net.core.netdev_max_backlog = 5000
|
||||
net.ipv4.tcp_max_syn_backlog = 8192
|
||||
net.ipv4.tcp_sack = 1
|
||||
net.ipv4.tcp_timestamps = 1
|
||||
|
||||
# Memory optimization
|
||||
vm.swappiness = 10
|
||||
vm.dirty_ratio = 30
|
||||
vm.dirty_background_ratio = 5
|
||||
vm.vfs_cache_pressure = 50
|
||||
|
||||
# File system
|
||||
fs.file-max = 1048576
|
||||
fs.inotify.max_user_watches = 1048576
|
||||
|
||||
# Process scheduler
|
||||
kernel.sched_autogroup_enabled = 0
|
||||
kernel.sched_migration_cost_ns = 5000000
|
||||
EOF
|
||||
|
||||
sysctl -p /etc/sysctl.d/99-sunhpc.conf &>/dev/null
|
||||
log_info "System optimization configured"
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# 13. 配置系统限制
|
||||
# ============================================================================
|
||||
|
||||
configure_limits() {
|
||||
log_step "Configuring system limits..."
|
||||
|
||||
cat > /etc/security/limits.d/99-sunhpc.conf << EOF
|
||||
# Sun HPC System Limits
|
||||
* soft nofile 1048576
|
||||
* hard nofile 1048576
|
||||
* soft nproc 131072
|
||||
* hard nproc 131072
|
||||
* soft memlock unlimited
|
||||
* hard memlock unlimited
|
||||
root soft nofile 1048576
|
||||
root hard nofile 1048576
|
||||
EOF
|
||||
|
||||
log_info "System limits configured"
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# 14. 配置定时任务
|
||||
# ============================================================================
|
||||
|
||||
configure_crontab() {
|
||||
log_step "Configuring cron jobs..."
|
||||
|
||||
cat > /etc/cron.d/sunhpc << EOF
|
||||
# Sun HPC Cron Jobs
|
||||
|
||||
# Sync time every hour
|
||||
0 * * * * root /usr/sbin/chronyc -a makestep &>/dev/null
|
||||
|
||||
# Clean old logs daily
|
||||
0 2 * * * root find /var/log -name "*.log" -mtime +30 -delete 2>/dev/null
|
||||
|
||||
# Report node status every 5 minutes
|
||||
*/5 * * * * root /usr/local/bin/node-status-report &>/dev/null
|
||||
EOF
|
||||
|
||||
chmod 644 /etc/cron.d/sunhpc
|
||||
log_info "Cron jobs configured"
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# 15. 创建节点状态上报脚本
|
||||
# ============================================================================
|
||||
|
||||
create_report_script() {
|
||||
log_step "Creating node status report script..."
|
||||
|
||||
cat > /usr/local/bin/node-status-report << 'EOF'
|
||||
#!/bin/bash
|
||||
# Node status report script for Sun HPC
|
||||
|
||||
HTTP_SERVER="http://172.16.9.254"
|
||||
NODE_NAME=$(hostname)
|
||||
IP_ADDR=$(ip -4 addr show | grep -oP '(?<=inet\s)\d+(\.\d+){3}' | grep -v '127.0.0.1' | head -1)
|
||||
LOAD_AVG=$(uptime | awk -F'load average:' '{print $2}' | cut -d, -f1)
|
||||
MEM_TOTAL=$(free -g | awk '/^Mem:/{print $2}')
|
||||
MEM_USED=$(free -g | awk '/^Mem:/{print $3}')
|
||||
DISK_USED=$(df -h / | awk 'NR==2{print $5}' | sed 's/%//')
|
||||
SLURM_STATUS=$(systemctl is-active slurm-slurmd 2>/dev/null || echo "unknown")
|
||||
|
||||
# Build status JSON
|
||||
STATUS_JSON="{\"node\":\"$NODE_NAME\",\"ip\":\"$IP_ADDR\",\"load\":$LOAD_AVG,\"mem_total\":$MEM_TOTAL,\"mem_used\":$MEM_USED,\"disk_used\":$DISK_USED,\"slurm\":\"$SLURM_STATUS\",\"timestamp\":\"$(date -Iseconds)\"}"
|
||||
|
||||
# Send to management node
|
||||
curl -s -X POST -H "Content-Type: application/json" -d "$STATUS_JSON" ${HTTP_SERVER}/api/node-status &>/dev/null
|
||||
EOF
|
||||
|
||||
chmod +x /usr/local/bin/node-status-report
|
||||
log_info "Node status report script created"
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# 16. 配置日志轮转
|
||||
# ============================================================================
|
||||
|
||||
configure_logrotate() {
|
||||
log_step "Configuring log rotation..."
|
||||
|
||||
cat > /etc/logrotate.d/sunhpc << EOF
|
||||
/var/log/sunhpc-init.log {
|
||||
daily
|
||||
rotate 30
|
||||
compress
|
||||
delaycompress
|
||||
missingok
|
||||
notifempty
|
||||
create 644 root root
|
||||
}
|
||||
EOF
|
||||
|
||||
log_info "Log rotation configured"
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# 17. 清理临时文件
|
||||
# ============================================================================
|
||||
|
||||
cleanup() {
|
||||
log_step "Cleaning up temporary files..."
|
||||
|
||||
# 删除临时文件
|
||||
rm -f /tmp/hostname-map.txt 2>/dev/null
|
||||
rm -f /tmp/cluster-hosts.txt 2>/dev/null
|
||||
|
||||
# 清除 YUM 缓存
|
||||
yum clean all &>/dev/null
|
||||
|
||||
log_info "Cleanup completed"
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# 18. 生成初始化完成报告
|
||||
# ============================================================================
|
||||
|
||||
generate_report() {
|
||||
log_step "Generating initialization report..."
|
||||
|
||||
cat > /root/init-report.txt << EOF
|
||||
===========================================
|
||||
Sun HPC Node Initialization Report
|
||||
===========================================
|
||||
Init Time: $(date '+%Y-%m-%d %H:%M:%S')
|
||||
Hostname: $(hostname)
|
||||
IP Address: $(ip -4 addr show | grep -oP '(?<=inet\s)\d+(\.\d+){3}' | grep -v '127.0.0.1' | head -1)
|
||||
MAC Address: $(ip link show | grep -oP 'ether \K[0-9a-f:]+' | head -1)
|
||||
|
||||
Services Status:
|
||||
- NetworkManager: $(systemctl is-active NetworkManager)
|
||||
- chronyd: $(systemctl is-active chronyd 2>/dev/null || echo "stopped")
|
||||
- sshd: $(systemctl is-active sshd)
|
||||
- slurm-slurmd: $(systemctl is-active slurm-slurmd 2>/dev/null || echo "stopped")
|
||||
- firewalld: $(systemctl is-active firewalld)
|
||||
|
||||
YUM Repositories:
|
||||
$(yum repolist)
|
||||
|
||||
Files Created:
|
||||
- /.sunhpc-release
|
||||
- /etc/hosts (updated)
|
||||
- /etc/motd (updated)
|
||||
- /etc/yum.repos.d/sunhpc-local.repo
|
||||
- /etc/chrony.conf (updated)
|
||||
- /etc/security/limits.d/99-sunhpc.conf
|
||||
- /etc/sysctl.d/99-sunhpc.conf
|
||||
|
||||
===========================================
|
||||
EOF
|
||||
|
||||
cat /root/init-report.txt >> $LOG_FILE
|
||||
log_info "Initialization report saved to /root/init-report.txt"
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# 主函数
|
||||
# ============================================================================
|
||||
|
||||
main() {
|
||||
log_info "Starting Sun HPC node initialization..."
|
||||
|
||||
# 执行所有初始化步骤
|
||||
init_log
|
||||
check_network
|
||||
create_release_file
|
||||
configure_hostname
|
||||
configure_motd
|
||||
configure_yum_repo
|
||||
configure_dns
|
||||
configure_ntp
|
||||
configure_ssh
|
||||
configure_firewall
|
||||
install_packages
|
||||
configure_slurm
|
||||
configure_user_env
|
||||
configure_sysctl
|
||||
configure_limits
|
||||
configure_crontab
|
||||
create_report_script
|
||||
configure_logrotate
|
||||
cleanup
|
||||
generate_report
|
||||
|
||||
log_info "=========================================="
|
||||
log_info "Sun HPC node initialization completed!"
|
||||
log_info "=========================================="
|
||||
|
||||
# 显示关键信息
|
||||
echo ""
|
||||
echo -e "${GREEN}=== Initialization Complete ===${NC}"
|
||||
echo -e "Hostname: $(hostname)"
|
||||
echo -e "Release file: $(cat /.sunhpc-release | head -1)"
|
||||
echo -e "Log file: $LOG_FILE"
|
||||
echo -e "Report: /root/init-report.txt"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# 脚本入口
|
||||
# ============================================================================
|
||||
|
||||
# 检查是否需要重启
|
||||
if [[ "$1" == "--reboot" ]]; then
|
||||
main
|
||||
log_info "Rebooting in 5 seconds..."
|
||||
sleep 5
|
||||
reboot
|
||||
else
|
||||
main
|
||||
log_info "Initialization completed. You may reboot if needed."
|
||||
fi
|
||||
21
pkgs/ks/ipxe.sh
Normal file
21
pkgs/ks/ipxe.sh
Normal file
@@ -0,0 +1,21 @@
|
||||
#!ipxe
|
||||
|
||||
:main_menu
|
||||
menu iPXE boot menu
|
||||
|
||||
item rocky9 Install Rocky Linux 9
|
||||
item local Boot from Local Disk
|
||||
|
||||
choose --default rocky9 --timeout 5000 selected || goto local
|
||||
|
||||
:rocky9
|
||||
echo Booting RockyLinux from networking
|
||||
kernel http://172.16.9.254/rocky/9.7/isolinux/vmlinuz \
|
||||
net.ifnames=0 biosdevname=0 \
|
||||
inst.repo=http://172.16.9.254/rocky/9.7 \
|
||||
inst.ks=http://172.16.9.254/ks/rhel.ks
|
||||
initrd http://172.16.9.254/rocky/9.7/isolinux/initrd.img
|
||||
boot
|
||||
|
||||
:local
|
||||
exit
|
||||
60
pkgs/ks/rhel.ks
Normal file
60
pkgs/ks/rhel.ks
Normal file
@@ -0,0 +1,60 @@
|
||||
graphical
|
||||
|
||||
%addon com_redhat_kdump --disable
|
||||
%end
|
||||
|
||||
timezone Asia/Shanghai --utc
|
||||
keyboard --xlayouts='us'
|
||||
lang en_US.UTF-8
|
||||
|
||||
selinux --disabled
|
||||
|
||||
url --url="http://172.16.9.254/rocky/9.7"
|
||||
|
||||
# Network information
|
||||
network --bootproto=dhcp --device=link --ipv6=auto --activate
|
||||
|
||||
# Partition clearing information
|
||||
#zerombr
|
||||
#clearpart --all --initlabel
|
||||
#autopart --type=lvm
|
||||
%include /tmp/diskinfo
|
||||
|
||||
#ignoredisk --only-use=sda
|
||||
#part /boot --fstype="xfs" --ondisk=sda --size=1024
|
||||
#part swap --fstype="swap" --ondisk=sda --size=4096
|
||||
#part / --fstype="xfs" --ondisk=sda --size=97278
|
||||
#part /home --fstype="xfs" --ondisk=sda --size=20480
|
||||
|
||||
%packages
|
||||
@^minimal-environment
|
||||
@standard
|
||||
@development
|
||||
vim
|
||||
wget
|
||||
curl
|
||||
autofs
|
||||
nfs-utils
|
||||
nfs4-acl-tools
|
||||
sssd-nfs-idmap
|
||||
pcp-pmda-nfsclient
|
||||
%end
|
||||
|
||||
# Root password
|
||||
rootpw --iscrypted $6$muqhPjb0F9IM2/Fg$pPaVF7DTjs/zz91vHMrcL8jPLQoLFCjUUxHkIZao9C6OFbBPof2AtmTRfvO4Ix.8al3dnMz8/aAbd88sHSQTK.
|
||||
user --name=kelvin --password=$6$kAz6MRJFIpIyhKuv$YZntcNpyoSYRMD6y5qmZIIBiklzaskqHWE4A0oXI8vX492bcL/.z6xF3MjVDgVJzZ0FaNDSy8BFeEhD9mfr67/ --iscrypted --gecos="kelvin"
|
||||
|
||||
#reboot
|
||||
|
||||
%pre --interpreter=/bin/bash
|
||||
curl -o /tmp/dfmt.sh http://172.16.9.254/ks/dfmt.sh
|
||||
chmod +x /tmp/dfmt.sh
|
||||
|
||||
/tmp/dfmt.sh > /tmp/diskinfo
|
||||
%end
|
||||
|
||||
%post
|
||||
curl -s -o /tmp/init.sh http://172.16.9.254/ks/init.sh
|
||||
chmod +x /tmp/init.sh
|
||||
/tmp/init.sh
|
||||
%end
|
||||
Reference in New Issue
Block a user