date
This commit is contained in:
24
htool.conf
Normal file
24
htool.conf
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
# ====================================================
|
||||||
|
# Generated by htool commands
|
||||||
|
# ====================================================
|
||||||
|
|
||||||
|
interface eth1
|
||||||
|
server 172.16.9.254
|
||||||
|
pkgsroot /srv/htool/pkgs/
|
||||||
|
wwwroot /var/www/html/linux
|
||||||
|
tftpboot /srv/pxelinux/tftpboot
|
||||||
|
startip 172.16.9.10
|
||||||
|
endip 172.16.9.90
|
||||||
|
dns 223.5.5.5
|
||||||
|
osname rockylinux
|
||||||
|
osvers 9.7
|
||||||
|
ospath rockylinux/9.7
|
||||||
|
lrepo /srv/repos/rockylinux
|
||||||
|
bios /srv/pxelinux/tftpboot/boot/undionly.kpxe
|
||||||
|
uefi /srv/pxelinux/tftpboot/boot/bootx64.efi
|
||||||
|
dfmt http://172.16.9.254/linux/ks/dfmt.sh
|
||||||
|
ksaddr http://172.16.9.254/linux/ks/rhel.ks
|
||||||
|
ipxeboot http://172.16.9.254/linux/ks/ipxe.sh
|
||||||
|
repos http://172.16.9.254/linux/rockylinux/9.7
|
||||||
|
vmlinuz http://172.16.9.254/linux/rockylinux/9.7/images/pxeboot/vmlinuz
|
||||||
|
initrd http://172.16.9.254/linux/rockylinux/9.7/images/pxeboot/initrd.img
|
||||||
@@ -14,14 +14,14 @@ set -e
|
|||||||
# 日志文件
|
# 日志文件
|
||||||
LOG_FILE="/var/log/sunhpc-init.log"
|
LOG_FILE="/var/log/sunhpc-init.log"
|
||||||
|
|
||||||
FRONTEND_IP="172.16.9.254"
|
FRONTEND_IP='@osipaddr@'
|
||||||
|
|
||||||
# HTTP 服务器地址
|
# HTTP 服务器地址
|
||||||
HTTP_SERVER="http://${FRONTEND_IP}"
|
HTTP_SERVER="http://${FRONTEND_IP}"
|
||||||
|
|
||||||
# YUM 仓库配置
|
# YUM 仓库配置
|
||||||
YUM_REPO_NAME="sunhpc-local"
|
YUM_REPO_NAME="sunhpc-local"
|
||||||
YUM_REPO_BASEURL="${HTTP_SERVER}/rocky/9.7"
|
YUM_REPO_BASEURL="${HTTP_SERVER}/@ospath@"
|
||||||
YUM_REPO_GPGCHECK=0
|
YUM_REPO_GPGCHECK=0
|
||||||
|
|
||||||
# 主机名映射文件(在 HTTP 服务器上)
|
# 主机名映射文件(在 HTTP 服务器上)
|
||||||
@@ -79,7 +79,7 @@ check_network() {
|
|||||||
log_step "Checking network connectivity..."
|
log_step "Checking network connectivity..."
|
||||||
|
|
||||||
# 测试网络连接
|
# 测试网络连接
|
||||||
if ping -c 1 -W 3 172.16.9.254 &>/dev/null; then
|
if ping -c 1 -W 3 FRONTEND_IP &>/dev/null; then
|
||||||
log_info "Network connectivity: OK"
|
log_info "Network connectivity: OK"
|
||||||
return 0
|
return 0
|
||||||
else
|
else
|
||||||
@@ -164,8 +164,6 @@ $ip_addr $hostname
|
|||||||
$FRONTEND_IP cluster
|
$FRONTEND_IP cluster
|
||||||
|
|
||||||
# Optional: Add other compute nodes here
|
# Optional: Add other compute nodes here
|
||||||
# 172.16.9.1 cn001
|
|
||||||
# 172.16.9.2 cn002
|
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
# 尝试下载完整的集群 hosts 文件
|
# 尝试下载完整的集群 hosts 文件
|
||||||
|
|||||||
@@ -3,18 +3,18 @@
|
|||||||
:main_menu
|
:main_menu
|
||||||
menu iPXE boot menu
|
menu iPXE boot menu
|
||||||
|
|
||||||
item rocky9 Install Rocky Linux 9
|
item @osname@ Install @osrels@ @osvers@
|
||||||
item local Boot from Local Disk
|
item local Boot from Local Disk
|
||||||
|
|
||||||
choose --default rocky9 --timeout 5000 selected || goto local
|
choose --default @osname@ --timeout 5000 selected || goto local
|
||||||
|
|
||||||
:rocky9
|
:@osname@
|
||||||
echo Booting RockyLinux from networking
|
echo Booting @osrels@ from networking
|
||||||
kernel http://172.16.9.254/rocky/9.7/isolinux/vmlinuz \
|
kernel @vmlinuz@ \
|
||||||
net.ifnames=0 biosdevname=0 \
|
@kargs@ \
|
||||||
inst.repo=http://172.16.9.254/rocky/9.7 \
|
@repos@ \
|
||||||
inst.ks=http://172.16.9.254/ks/rhel.ks
|
@ksarg@
|
||||||
initrd http://172.16.9.254/rocky/9.7/isolinux/initrd.img
|
initrd @initrds@
|
||||||
boot
|
boot
|
||||||
|
|
||||||
:local
|
:local
|
||||||
|
|||||||
@@ -1,35 +1,28 @@
|
|||||||
graphical
|
graphical
|
||||||
|
|
||||||
%addon com_redhat_kdump --disable
|
|
||||||
%end
|
|
||||||
|
|
||||||
timezone Asia/Shanghai --utc
|
timezone Asia/Shanghai --utc
|
||||||
keyboard --xlayouts='us'
|
keyboard --xlayouts="us"
|
||||||
lang en_US.UTF-8
|
lang en_US.UTF-8
|
||||||
|
|
||||||
selinux --disabled
|
selinux --disabled
|
||||||
|
|
||||||
url --url="http://172.16.9.254/rocky/9.7"
|
url --url='@url@'
|
||||||
|
|
||||||
# Network information
|
|
||||||
network --bootproto=dhcp --device=link --ipv6=auto --activate
|
network --bootproto=dhcp --device=link --ipv6=auto --activate
|
||||||
|
|
||||||
# Partition clearing information
|
# Partition clearing information
|
||||||
#zerombr
|
# zerombr
|
||||||
#clearpart --all --initlabel
|
# clearpart --all --initlabel
|
||||||
#autopart --type=lvm
|
# 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
|
||||||
|
# autopart --type=lvm
|
||||||
%include /tmp/diskinfo
|
%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
|
%packages
|
||||||
@^minimal-environment
|
@^minimal-environment
|
||||||
@standard
|
|
||||||
@development
|
@development
|
||||||
|
@standard
|
||||||
vim
|
vim
|
||||||
wget
|
wget
|
||||||
curl
|
curl
|
||||||
@@ -37,24 +30,23 @@ autofs
|
|||||||
nfs-utils
|
nfs-utils
|
||||||
nfs4-acl-tools
|
nfs4-acl-tools
|
||||||
sssd-nfs-idmap
|
sssd-nfs-idmap
|
||||||
pcp-pmda-nfsclient
|
|
||||||
%end
|
%end
|
||||||
|
|
||||||
# Root password
|
rootpw --plaintext admin_b101
|
||||||
rootpw --iscrypted $6$muqhPjb0F9IM2/Fg$pPaVF7DTjs/zz91vHMrcL8jPLQoLFCjUUxHkIZao9C6OFbBPof2AtmTRfvO4Ix.8al3dnMz8/aAbd88sHSQTK.
|
user --name=dell --plaintext admin_b101 --gecos="dell"
|
||||||
user --name=kelvin --password=$6$kAz6MRJFIpIyhKuv$YZntcNpyoSYRMD6y5qmZIIBiklzaskqHWE4A0oXI8vX492bcL/.z6xF3MjVDgVJzZ0FaNDSy8BFeEhD9mfr67/ --iscrypted --gecos="kelvin"
|
reboot
|
||||||
|
|
||||||
#reboot
|
|
||||||
|
|
||||||
%pre --interpreter=/bin/bash
|
%pre --interpreter=/bin/bash
|
||||||
curl -o /tmp/dfmt.sh http://172.16.9.254/ks/dfmt.sh
|
curl -o /tmp/dfmt.sh @dfmt@
|
||||||
chmod +x /tmp/dfmt.sh
|
chmod +x /tmp/dfmt.sh
|
||||||
|
|
||||||
/tmp/dfmt.sh > /tmp/diskinfo
|
/tmp/dfmt.sh > /tmp/diskinfo
|
||||||
%end
|
%end
|
||||||
|
|
||||||
%post
|
%post
|
||||||
curl -s -o /tmp/init.sh http://172.16.9.254/ks/init.sh
|
curl -s -o /tmp/init.sh @init@
|
||||||
chmod +x /tmp/init.sh
|
chmod +x /tmp/init.sh
|
||||||
/tmp/init.sh
|
/tmp/init.sh
|
||||||
%end
|
%end
|
||||||
|
|
||||||
|
%addon com_redhat_kdump --disable
|
||||||
|
%end
|
||||||
|
|||||||
683
sunhpc
683
sunhpc
@@ -74,40 +74,7 @@ DEFAULT_NODES=("localhost")
|
|||||||
GLOBAL_NODES=()
|
GLOBAL_NODES=()
|
||||||
declare -A GLOBAL_PORT
|
declare -A GLOBAL_PORT
|
||||||
declare -A global_env
|
declare -A global_env
|
||||||
|
declare -A global_treeinfo
|
||||||
ask() {
|
|
||||||
# 基本用法:ask "是否删除文件?" - 无默认值,必须输入 y/yes 或 n/no
|
|
||||||
# ask "是否继续?" "y" - 默认继续,直接回车相当于 y
|
|
||||||
# ask "是否继续?" "n" - 默认取消,直接回车相当于 n
|
|
||||||
# if ask "警告:即将删除所有文件,是否继续?" "n"; then
|
|
||||||
local prompt="$1"
|
|
||||||
local default="$2"
|
|
||||||
local answer
|
|
||||||
|
|
||||||
# 构建提示信息
|
|
||||||
if [ "$default" = "y" ]; then
|
|
||||||
prompt="$prompt [Y/n]: "
|
|
||||||
elif [ "$default" = "n" ]; then
|
|
||||||
prompt="$prompt [y/N]: "
|
|
||||||
else
|
|
||||||
prompt="$prompt [y/n]: "
|
|
||||||
fi
|
|
||||||
|
|
||||||
while true; do
|
|
||||||
read -p "$prompt" answer
|
|
||||||
# 如果用户直接回车,使用默认值
|
|
||||||
if [ -z "$answer" ] && [ -n "$default" ]; then
|
|
||||||
answer="$default"
|
|
||||||
fi
|
|
||||||
# 转换为小写进行比较
|
|
||||||
answer=$(echo "$answer" | tr '[:upper:]' '[:lower:]')
|
|
||||||
case "$answer" in
|
|
||||||
y|yes) return 0 ;;
|
|
||||||
n|no) return 1 ;;
|
|
||||||
*) echo "请输入 y/yes 或 n/no" ;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
load_os_envs() {
|
load_os_envs() {
|
||||||
interfaces=$(ls /sys/class/net | grep -v lo)
|
interfaces=$(ls /sys/class/net | grep -v lo)
|
||||||
@@ -132,6 +99,49 @@ load_os_envs() {
|
|||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
|
load_conf_envs() {
|
||||||
|
|
||||||
|
while read -r key val; do
|
||||||
|
# 跳过空行、注释行
|
||||||
|
[[ -z "$key" || "$key" == \#* ]] && continue
|
||||||
|
|
||||||
|
global_env["$key"]="$val"
|
||||||
|
done < "$config_file"
|
||||||
|
}
|
||||||
|
|
||||||
|
parse_treeinfo() {
|
||||||
|
local treeinfo_file="${1:-.treeinfo}"
|
||||||
|
local current_section=""
|
||||||
|
|
||||||
|
while IFS= read -r line || [[ -n "$line" ]]; do
|
||||||
|
# 跳过空行和注释行
|
||||||
|
[[ -z "$line" || "$line" =~ ^[[:space:]]*\; ]] && continue
|
||||||
|
|
||||||
|
# 匹配 section,例如 [general]
|
||||||
|
if [[ "$line" =~ ^\[([^]]+)\]$ ]]; then
|
||||||
|
current_section="${BASH_REMATCH[1]}"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 匹配 key = value
|
||||||
|
if [[ "$line" =~ ^[[:space:]]*([^=]+)[[:space:]]*=[[:space:]]*(.*)$ ]]; then
|
||||||
|
local key="${BASH_REMATCH[1]}"
|
||||||
|
local value="${BASH_REMATCH[2]}"
|
||||||
|
|
||||||
|
key="${key#"${key%%[![:space:]]*}"}"
|
||||||
|
key="${key%"${key##*[![:space:]]}"}"
|
||||||
|
|
||||||
|
# 去除值两端和中间的所有空格
|
||||||
|
value="${value#"${value%%[![:space:]]*}"}"
|
||||||
|
value="${value%"${value##*[![:space:]]}"}"
|
||||||
|
value=$(echo "$value" | tr -d ' ' | tr '[:upper:]' '[:lower:]')
|
||||||
|
|
||||||
|
# 存储到关联数组,使用 "section.key" 作为键名
|
||||||
|
global_treeinfo["${current_section}.${key}"]="$value"
|
||||||
|
fi
|
||||||
|
done < "$treeinfo_file"
|
||||||
|
}
|
||||||
|
|
||||||
getFileArgs(){
|
getFileArgs(){
|
||||||
# 调用模式: getFileArgs myfile "true" 未指定文件时只返回错误码
|
# 调用模式: getFileArgs myfile "true" 未指定文件时只返回错误码
|
||||||
# 调用模式: result=$(getFileArgs myfile "true") 返回文件
|
# 调用模式: result=$(getFileArgs myfile "true") 返回文件
|
||||||
@@ -168,15 +178,44 @@ getFileArgs(){
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# ====================== 核心函数:加载环境变量信息 ==============
|
getArgs() {
|
||||||
load_conf_envs() {
|
# getArgs interface iface e "msg"
|
||||||
|
local key="$1"
|
||||||
|
local result="$2"
|
||||||
|
local level="${3:-w}" # 默认级别为 warn
|
||||||
|
local msg="${4:-}"
|
||||||
|
local value=""
|
||||||
|
|
||||||
while read -r key val; do
|
# 优先级1:检查 GLOBAL_OPTS(命令行参数)
|
||||||
# 跳过空行、注释行
|
if [[ -n "${GLOBAL_OPTS[$key]}" ]]; then
|
||||||
[[ -z "$key" || "$key" == \#* ]] && continue
|
value="${GLOBAL_OPTS[$key]}"
|
||||||
|
# 优先级2:检查 global_env(配置文件)
|
||||||
|
elif [[ -n "${global_env[$key]}" ]]; then
|
||||||
|
value="${global_env[$key]}"
|
||||||
|
fi
|
||||||
|
|
||||||
global_env["$key"]="$val"
|
# 检查 GLOBAL_OPTS 数组中是否存在该键
|
||||||
done < "$config_file"
|
if [[ -n "$value" ]]; then
|
||||||
|
printf -v "$result" "%s" "$value"
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
# 根据不同的级别处理错误
|
||||||
|
case "$level" in
|
||||||
|
e)
|
||||||
|
[[ -n "$msg" ]] && error "$msg" || error "必须指定 --$key 参数"
|
||||||
|
;;
|
||||||
|
w)
|
||||||
|
[[ -n "$msg" ]] && warn "$msg" || warn "未指定 --$key 参数,将使用默认值或跳过"
|
||||||
|
;;
|
||||||
|
i)
|
||||||
|
[[ -n "$msg" ]] && info "$msg" || info "未指定 --$key 参数"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
[[ -n "$msg" ]] && info "$msg" || info "未指定 --$key 参数"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# ============================================================
|
# ============================================================
|
||||||
@@ -189,30 +228,6 @@ print_global_env() {
|
|||||||
echo "======================================"
|
echo "======================================"
|
||||||
}
|
}
|
||||||
|
|
||||||
# ============================================================
|
|
||||||
# 辅助函数:获取指定网卡IP
|
|
||||||
# ============================================================
|
|
||||||
get_interface_ip() {
|
|
||||||
local interface="$1"
|
|
||||||
if ip link show "$interface" &>/dev/null; then
|
|
||||||
ip addr show "$interface" | grep -oP '(?<=inet\s)\d+(\.\d+){3}' | head -1
|
|
||||||
else
|
|
||||||
echo ""
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# ============================================================
|
|
||||||
# 辅助函数:获取指定网卡MAC地址
|
|
||||||
# ============================================================
|
|
||||||
get_interface_mac() {
|
|
||||||
local interface="$1"
|
|
||||||
if ip link show "$interface" &>/dev/null; then
|
|
||||||
ip link show "$interface" | grep -oP '(?<=link/ether\s)[0-9a-f:]+' | head -1
|
|
||||||
else
|
|
||||||
echo ""
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# ============================================================
|
# ============================================================
|
||||||
# 辅助函数:快速获取系统信息摘要
|
# 辅助函数:快速获取系统信息摘要
|
||||||
# ============================================================
|
# ============================================================
|
||||||
@@ -360,157 +375,6 @@ get_subnet_address() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
# ====================== pxe server functions ====================
|
# ====================== pxe server functions ====================
|
||||||
pxe_dhcp_build() {
|
|
||||||
log_debug "当前节点:${GLOBAL_NODES[*]}"
|
|
||||||
log_debug "公共参数:${PUBLIC_ARGS[*]}"
|
|
||||||
log_debug "私有参数:${PRIVATE_ARGS[*]}"
|
|
||||||
|
|
||||||
interface="${GLOBAL_OPTS[interface]}"
|
|
||||||
ipaddr=${global_env[${interface}_ip]}
|
|
||||||
netcidr=${global_env[${interface}_mask]}
|
|
||||||
netmask=$(cidr_to_netmask 24)
|
|
||||||
subnet=$(get_subnet_address $ipaddr $netmask)
|
|
||||||
|
|
||||||
IFS=. read -r i1 i2 i3 i4 <<< "$ipaddr"
|
|
||||||
start_ip="$i1.$i2.$i3.10"
|
|
||||||
ender_ip="$i1.$i2.$i3.90"
|
|
||||||
tests_ip="$i1.$i2.$i3.252"
|
|
||||||
|
|
||||||
info "DHCP Interface name: $interface"
|
|
||||||
info "DHCP IP Address : $ipaddr"
|
|
||||||
info "DHCP IP Netmask : $netmask"
|
|
||||||
info "DHCP IP Subnets : $subnet"
|
|
||||||
info "DHCP Start IPAddr : $start_ip"
|
|
||||||
info "DHCP End IPAddr : $ender_ip"
|
|
||||||
|
|
||||||
nopkgs=()
|
|
||||||
pkgs=("dhcp-server dhcp-common")
|
|
||||||
filter_pkgs pkgs nopkgs
|
|
||||||
|
|
||||||
local cmd=("dnf -y install ${nopkgs[*]}")
|
|
||||||
[[ -z ${nopkgs[@]} ]] || run_with_progress "DNF 安装DHCP服务..." "$cmd" "$log_file"
|
|
||||||
|
|
||||||
dhcp_config="/etc/dhcp/dhcpd.conf"
|
|
||||||
|
|
||||||
{
|
|
||||||
echo "option domain-name \"`hostname -s`\";"
|
|
||||||
echo "option domain-name-servers 8.8.8.8;"
|
|
||||||
echo "default-lease-time 600;"
|
|
||||||
echo "max-lease-time 7200;"
|
|
||||||
echo "ddns-update-style none;"
|
|
||||||
echo ""
|
|
||||||
echo "allow booting;"
|
|
||||||
echo "allow bootp;"
|
|
||||||
echo ""
|
|
||||||
echo "option arch code 93 = unsigned integer 16;"
|
|
||||||
echo ""
|
|
||||||
echo "subnet ${subnet} netmask ${netmask} {"
|
|
||||||
echo " option routers ${ipaddr};"
|
|
||||||
echo " range $start_ip $ender_ip;"
|
|
||||||
echo ""
|
|
||||||
echo " next-server ${ipaddr};"
|
|
||||||
echo ""
|
|
||||||
echo ' host test_host_bond {'
|
|
||||||
echo ' option dhcp-client-identifier "test_host_bond";'
|
|
||||||
echo " fixed-address $tests_ip;"
|
|
||||||
echo ' }'
|
|
||||||
echo ' if option arch= 00:07 or option arch = 00:09 {'
|
|
||||||
echo ' # UEFI x64'
|
|
||||||
echo ' filename "/EFI/x86/grub.efi";'
|
|
||||||
echo ' } else if option arch = 00:0b {'
|
|
||||||
echo ' # UEFI ARM64'
|
|
||||||
echo ' filename "/EFI/aarch64/bootaa64.efi";'
|
|
||||||
echo ' } else {'
|
|
||||||
echo ' # Legcy BIOS'
|
|
||||||
echo ' filename "pxelinux.0";'
|
|
||||||
echo ' }'
|
|
||||||
echo '}'
|
|
||||||
} > ${dhcp_config}
|
|
||||||
|
|
||||||
# sed -i 's/\$DHCPDARGS/eth0/' /usr/lib/systemd/system/dhcpd.service
|
|
||||||
dhcp_systemd="/usr/lib/systemd/system/dhcpd.service"
|
|
||||||
grep -q "DHCPDARGS" $dhcp_systemd &>/dev/null && \
|
|
||||||
sed -i "s/\$DHCPDARGS/${interface}/" $dhcp_systemd &>/dev/null
|
|
||||||
|
|
||||||
systemctl daemon-reload && systemctl restart dhcpd.service
|
|
||||||
systemctl is-enabled dhcpd &>/dev/null || systemctl enable dhcpd.service &>/dev/null
|
|
||||||
|
|
||||||
systemctl is-active dhcpd &>/dev/null && info "DHCP 服务已经配置成功..." \
|
|
||||||
|| warn "DHCP 服务部署失败,请查看服务信息 systemctl status dhcpd.service"
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
pxe_tftp_build() {
|
|
||||||
log_debug "当前节点:${GLOBAL_NODES[*]}"
|
|
||||||
log_debug "公共参数:${PUBLIC_ARGS[*]}"
|
|
||||||
log_debug "私有参数:${PRIVATE_ARGS[*]}"
|
|
||||||
|
|
||||||
nopkgs=()
|
|
||||||
pkgs=("tftp-server tftp syslinux")
|
|
||||||
filter_pkgs pkgs nopkgs
|
|
||||||
|
|
||||||
local cmd=("dnf -y install ${nopkgs[*]}")
|
|
||||||
[[ -z ${nopkgs[@]} ]] || run_with_progress "DNF 安装TFTP服务..." "$cmd" "$log_file"
|
|
||||||
|
|
||||||
tftp_server_conf="/usr/lib/systemd/system/tftp.service"
|
|
||||||
tftp_socket_conf="/usr/lib/systemd/system/tftp.socket"
|
|
||||||
tftp_pxe_dirs="/var/lib/tftpboot"
|
|
||||||
|
|
||||||
[[ -e "$tftp_pxe_dirs" ]] || mkdir -p "$tftp_pxe_dirs/pxelinux.cfg"
|
|
||||||
chmod -R 755 $tftp_pxe_dirs
|
|
||||||
|
|
||||||
# Pxe 启动文件配置
|
|
||||||
src_pxelinux="/usr/share/syslinux"
|
|
||||||
src_files=("pxelinux.0 menu.c32 ldlinux.c32")
|
|
||||||
for fname in ${src_files[@]}; do
|
|
||||||
src_file="$src_pxelinux/$fname"
|
|
||||||
dst_file="$tftp_pxe_dirs/$fname"
|
|
||||||
|
|
||||||
[[ -f $src_file ]] || warn "$src_file not found!"
|
|
||||||
|
|
||||||
if [[ -f $dst_file ]]; then
|
|
||||||
info "The $fname already exists, Skipt shis copy..."
|
|
||||||
else
|
|
||||||
info "Copying the $fname to $dst_file"
|
|
||||||
/usr/bin/cp $src_file $dst_file
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
# 文件配置
|
|
||||||
if ! getFileArgs myfile "true"; then
|
|
||||||
warn " 必须指定系统ISO文件或挂载位置,例如: "
|
|
||||||
warn " -f /root/Rocky-9.7-x86_64-dvd.iso 或 -f /mnt/cdrom/"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "------------> $myfile"
|
|
||||||
|
|
||||||
exit 1
|
|
||||||
|
|
||||||
# -c 允许创建新文件(上传) -p 使用普通系统权限检查
|
|
||||||
{
|
|
||||||
echo '[Unit]'
|
|
||||||
echo 'Description=Tftp Server'
|
|
||||||
echo 'Requires=tftp.socket'
|
|
||||||
echo 'Documentation=man:in.tftpd'
|
|
||||||
echo ''
|
|
||||||
echo '[Service]'
|
|
||||||
echo "ExecStart=/usr/sbin/in.tftpd -c -p -s "$tftp_pxe_dirs""
|
|
||||||
echo 'StandardInput=socket'
|
|
||||||
echo ''
|
|
||||||
echo '[Install]'
|
|
||||||
echo 'WantedBy=multi-user.target'
|
|
||||||
echo 'Also=tftp-server.socket'
|
|
||||||
} > ${tftp_server_conf}
|
|
||||||
|
|
||||||
systemctl daemon-reload && systemctl restart tftp.socket
|
|
||||||
systemctl is-enabled tftp.socket &>/dev/null || systemctl enable tftp.socket &>/dev/null
|
|
||||||
|
|
||||||
info "TFTP 服务端口: 69"
|
|
||||||
systemctl is-active tftp.socket &>/dev/null && info "TFTP 服务已经配置成功..." \
|
|
||||||
|| warn "TFTP 服务部署失败,请查看服务信息 systemctl status tftp.socket"
|
|
||||||
}
|
|
||||||
|
|
||||||
pxe_http_build() {
|
pxe_http_build() {
|
||||||
log_debug "当前节点:${GLOBAL_NODES[*]}"
|
log_debug "当前节点:${GLOBAL_NODES[*]}"
|
||||||
log_debug "公共参数:${PUBLIC_ARGS[*]}"
|
log_debug "公共参数:${PUBLIC_ARGS[*]}"
|
||||||
@@ -530,12 +394,12 @@ pxe_http_build() {
|
|||||||
|
|
||||||
custom_conf="$http_root_conf/conf.d/sunhpc.conf"
|
custom_conf="$http_root_conf/conf.d/sunhpc.conf"
|
||||||
{
|
{
|
||||||
echo 'Alias /rocky97 /var/www/html/rocky97'
|
echo 'Alias /linux /var/www/html/linux'
|
||||||
echo ''
|
echo ''
|
||||||
echo 'UseCanonicalName Off'
|
echo 'UseCanonicalName Off'
|
||||||
echo "ServerName `hostname -f`"
|
echo "ServerName `hostname -f`"
|
||||||
echo ''
|
echo ''
|
||||||
echo "<Directory \"$rocky_dirs\">"
|
echo '<Directory "/var/www/html/linux">'
|
||||||
echo " Options Indexes FollowSymLinks"
|
echo " Options Indexes FollowSymLinks"
|
||||||
echo " AllowOverride None"
|
echo " AllowOverride None"
|
||||||
echo " Require all granted"
|
echo " Require all granted"
|
||||||
@@ -548,52 +412,12 @@ pxe_http_build() {
|
|||||||
#systemctl is-enabled httpd &>/dev/null || systemctl enable httpd &>/dev/null
|
#systemctl is-enabled httpd &>/dev/null || systemctl enable httpd &>/dev/null
|
||||||
|
|
||||||
|
|
||||||
info "HTTP 服务端口: 80,443"
|
|
||||||
if systemctl is-active httpd &>/dev/null ; then
|
if systemctl is-active httpd &>/dev/null ; then
|
||||||
info "HTTP 服务已经配置成功..."
|
info "HTTP 服务部署成功"
|
||||||
info "后续配置: "
|
info "HTTP 服务端口: 80,443"
|
||||||
info " 拷贝系统ISO文件到 $rocky_repo_src"
|
|
||||||
info " # rsync -ah --info=progress2 /mnt/ /srv/repos/rocky/9.7/"
|
|
||||||
else
|
else
|
||||||
warn "HTTP 服务部署失败,请查看服务信息 systemctl status httpd.service"
|
warn "HTTP 服务部署失败,请查看服务信息 systemctl status httpd.service"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if getFileArgs myfile "true"; then
|
|
||||||
local mnt_iso_dirs=$myfile
|
|
||||||
if [[ -f $myfile ]]; then
|
|
||||||
mnt_dst_dirs="/mnt/cdrom"
|
|
||||||
[[ -e "$mnt_dst_dirs" ]] && umount $mnt_dst_dirs &>/dev/null || mkdir -p $mnt_dst_dirs
|
|
||||||
info "Mount path: $mnt_dst_dirs"
|
|
||||||
mount $myfile $mnt_dst_dirs &>/dev/null
|
|
||||||
mnt_iso_dirs=$mnt_dst_dirs
|
|
||||||
fi
|
|
||||||
|
|
||||||
rpmname=$(find $mnt_iso_dirs -iname "rocky-release-*.rpm")
|
|
||||||
filename=$(basename "$rpmname" .rpm)
|
|
||||||
distro=$(echo "$filename" | cut -d'-' -f1) # rocky
|
|
||||||
version=$(echo "$filename" | cut -d'-' -f3) # 9.7
|
|
||||||
distro=${distro:-"linux"}
|
|
||||||
version=${version:-"1.0"}
|
|
||||||
|
|
||||||
rocky_repo_distro="/srv/repos/$distro"
|
|
||||||
rocky_repo_version="$rocky_repo_distro/$version"
|
|
||||||
rocky_html_dst="$http_html_dirs/$distro"
|
|
||||||
[[ ! -e $rocky_repo_version ]] && mkdir -p $rocky_repo_version
|
|
||||||
[[ ! -e $rocky_html_dst ]] && ln -s $rocky_repo_distro $rocky_html_dst
|
|
||||||
|
|
||||||
info "拷贝系统镜像到本地: $rocky_repo_src"
|
|
||||||
info " 系统发行版: $distro"
|
|
||||||
info " 系统版本 : $version"
|
|
||||||
info " 源地址 : $mnt_iso_dirs"
|
|
||||||
info " 目的地址 : $rocky_repo_version"
|
|
||||||
|
|
||||||
rsync -ah --info=progress2 "$mnt_iso_dirs" "$rocky_repo_version/"
|
|
||||||
info "测试访问: curl -L http://`hostname -s`/$distro/$version/"
|
|
||||||
else
|
|
||||||
info "后续配置: "
|
|
||||||
info " 拷贝系统ISO文件到 $rocky_repo_src"
|
|
||||||
info " # rsync -ah --info=progress2 /mnt/ /srv/repos/rocky/9.7/"
|
|
||||||
fi
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pxe_dnsmasq_build() {
|
pxe_dnsmasq_build() {
|
||||||
@@ -608,53 +432,31 @@ pxe_dnsmasq_build() {
|
|||||||
local cmd=("dnf -y install ${nopkgs[*]}")
|
local cmd=("dnf -y install ${nopkgs[*]}")
|
||||||
[[ -z ${nopkgs[@]} ]] || run_with_progress "DNF 安装 dnsmasq 服务..." "$cmd" "$log_file"
|
[[ -z ${nopkgs[@]} ]] || run_with_progress "DNF 安装 dnsmasq 服务..." "$cmd" "$log_file"
|
||||||
|
|
||||||
# -n 非空True,-z 为空True
|
getArgs interface iface e "必须指定一个网络接口,例如: -i/--interface eth1"
|
||||||
[[ -n ${global_env[interface]} ]] && iface=${global_env[interface]} || \
|
getArgs server ipaddr e "Check the configuration file $config_file: server <ipaddr>"
|
||||||
error "请指定DHCP监听接口命名, 编辑 $config_file 文件, 例如: interface eth1"
|
getArgs tftpboot tftpboot e "Check the configuration file $config_file: tftpboot <fullpath>"
|
||||||
|
getArgs startip start_ip e "Check the configuration file $config_file: startip <ipaddr>"
|
||||||
|
getArgs endip ender_ip e "Check the configuration file $config_file: endip <ipaddr>"
|
||||||
|
getArgs dns dnsip e "Check the configuration file $config_file: dns <dnsaddr>"
|
||||||
|
|
||||||
[[ -n ${global_env[server]} ]] && ipaddr=${global_env[server]} || \
|
getArgs bios biosboot e "Check the configuration file $config_file: biosboot <fullpath>"
|
||||||
error "请指定监听接口IP地址, 编辑 $config_file 文件, 例如: server 172.16.9.254"
|
getArgs uefi uefiboot e "Check the configuration file $config_file: uefiboot <fullpath>"
|
||||||
|
getArgs ipxeboot ipxeboot e "Check the configuration file $config_file: ipxeboot <url>"
|
||||||
[[ -n ${global_env[dns]} ]] && dnsip=${global_env[dns]} || dnsip="223.5.5.5"
|
|
||||||
|
|
||||||
[[ -n ${global_env[range]} ]] && iprange=${global_env[range]} || \
|
|
||||||
error "请指定DHCP网络IP地址范围, 编辑 $config_file 文件, 例如: range 172.16.9.1,172.16.9.100"
|
|
||||||
|
|
||||||
vmlinuz="http://$ipaddr/rocky/isolinux/vmlinuz"
|
|
||||||
[[ -n ${global_env[vmlinuz]} ]] && vmlinuz=${global_env[vmlinuz]} || \
|
|
||||||
error "请指定vmlinuz web路径, 编辑 $config_file 文件, 例如: vmlinuz http://$ipaddr/rocky/isolinux/vmlinuz"
|
|
||||||
|
|
||||||
initrd="http://$ipaddr/rocky/isolinux/initrd.img"
|
|
||||||
[[ -n ${global_env[initrd]} ]] && initrd=${global_env[initrd]} || \
|
|
||||||
error "请指定initrd web路径, 编辑 $config_file 文件, 例如: initrd http://$ipaddr/rocky/isolinux/initrd.img"
|
|
||||||
[[ -n ${global_env[ks]} ]] && ks=${global_env[ks]} || \
|
|
||||||
error "请指定ks web路径, 编辑 $config_file 文件, 例如: ks http://$ipaddr/ks/ks.ks"
|
|
||||||
[[ -n ${global_env[repo]} ]] && repo=${global_env[repo]} || \
|
|
||||||
error "请指定ks web路径, 编辑 $config_file 文件, 例如: repo http://$ipaddr/rocky/"
|
|
||||||
|
|
||||||
kargs="net.ifnames=0 biosdevname=0"
|
|
||||||
[[ -n ${global_env[kargs]} ]] && kargs="$kargs ${global_env[kargs]}"
|
|
||||||
|
|
||||||
ipxeboot="http://$ipaddr/ks/boot.ipxe"
|
|
||||||
[[ -n ${global_env[bootipxe]} ]] && ipxeboot=${global_env[bootipxe]}
|
|
||||||
|
|
||||||
htmlroot="/var/www/html"
|
|
||||||
[[ -n ${global_env[htmlroot]} ]] && htmlroot=${global_env[htmlroot]}
|
|
||||||
|
|
||||||
|
|
||||||
boot_root="/srv/pxelinux/tftpboot"
|
biosboot="${biosboot#$tftpboot/}"
|
||||||
|
uefiboot="${uefiboot#$tftpboot/}"
|
||||||
dnsmasq_conf="/etc/dnsmasq.d/sunhpc.conf"
|
dnsmasq_conf="/etc/dnsmasq.d/sunhpc.conf"
|
||||||
|
|
||||||
[[ -e "$boot_root/boot" ]] || mkdir -p "$boot_root/boot"
|
|
||||||
{
|
{
|
||||||
echo "interface=$interface"
|
echo "interface=$iface"
|
||||||
echo "bind-interfaces"
|
echo "bind-interfaces"
|
||||||
echo ""
|
echo ""
|
||||||
echo "enable-tftp"
|
echo "enable-tftp"
|
||||||
echo "tftp-root=${boot_root}"
|
echo "tftp-root=${tftpboot}"
|
||||||
echo ""
|
echo ""
|
||||||
echo "# Gateway:3, DNS:6"
|
echo "# Gateway:3, DNS:6"
|
||||||
echo "dhcp-range=$iprange,12h"
|
echo "dhcp-range=$start_ip,$ender_ip,12h"
|
||||||
echo "dhcp-option=3,${ipaddr}"
|
echo "dhcp-option=3,${ipaddr}"
|
||||||
echo "dhcp-option=6,$dnsip"
|
echo "dhcp-option=6,$dnsip"
|
||||||
echo ""
|
echo ""
|
||||||
@@ -662,14 +464,11 @@ pxe_dnsmasq_build() {
|
|||||||
echo "dhcp-match=set:uefi,option:client-arch,7"
|
echo "dhcp-match=set:uefi,option:client-arch,7"
|
||||||
echo "dhcp-match=set:uefi,option:client-arch,9"
|
echo "dhcp-match=set:uefi,option:client-arch,9"
|
||||||
echo ""
|
echo ""
|
||||||
echo "dhcp-boot=tag:bios,boot/undionly.kpxe"
|
echo "dhcp-boot=tag:bios,$biosboot"
|
||||||
echo "dhcp-boot=tag:uefi,boot/bootx64.efi"
|
echo "dhcp-boot=tag:uefi,$uefiboot"
|
||||||
echo "dhcp-boot=tag:ipxe,$ipxeboot"
|
echo "dhcp-boot=tag:ipxe,$ipxeboot"
|
||||||
} > ${dnsmasq_conf}
|
} > ${dnsmasq_conf}
|
||||||
|
|
||||||
ipxeconf="$htmlroot$(echo "$htmlroot" | cut -d'/' -f4-)"
|
|
||||||
echo "----ipxeconf----> $ipxeconf"
|
|
||||||
|
|
||||||
}
|
}
|
||||||
# ====================== server functions ========================
|
# ====================== server functions ========================
|
||||||
slurm_build() {
|
slurm_build() {
|
||||||
@@ -1159,6 +958,111 @@ sync_file_single() {
|
|||||||
done
|
done
|
||||||
info "同步完成!"
|
info "同步完成!"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# rsync 同步函数,支持 ISO 文件和普通目录
|
||||||
|
# 用法: rsync_sync_file <source> <destination> [rsync_options]
|
||||||
|
# 参数:
|
||||||
|
# source - 源路径(文件或目录,支持 ISO 文件)
|
||||||
|
# destination - 目标路径
|
||||||
|
# rsync_options - 可选,额外的 rsync 参数
|
||||||
|
# 返回:
|
||||||
|
# 0 - 成功
|
||||||
|
# 1 - 失败
|
||||||
|
rsync_sync_file() {
|
||||||
|
local source="$1"
|
||||||
|
local destination="$2"
|
||||||
|
local rsync_opts="${3:--ah --info=progress2}" # 默认 rsync 选项
|
||||||
|
local temp_mount=""
|
||||||
|
local is_iso=false
|
||||||
|
local exit_code=0
|
||||||
|
|
||||||
|
# 检查参数
|
||||||
|
if [[ -z "$source" ]] || [[ -z "$destination" ]]; then
|
||||||
|
warn "必须指定源路径和目标路径" >&2
|
||||||
|
warn "用法: rsync_sync_file <source> <destination> [rsync_options]" >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 检查源路径是否存在
|
||||||
|
if [[ ! -e "$source" ]]; then
|
||||||
|
warn "源路径不存在: $source" >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 检查是否为 ISO 文件
|
||||||
|
if [[ -f "$source" && ( "$source" =~ \.(iso|ISO)$ ) ]]; then
|
||||||
|
is_iso=true
|
||||||
|
info "检测到 ISO 文件: $source"
|
||||||
|
|
||||||
|
# 创建临时挂载点
|
||||||
|
temp_mount=$(mktemp -d "/tmp/iso_mount_XXXXXX")
|
||||||
|
info "创建临时挂载点: $temp_mount"
|
||||||
|
|
||||||
|
# 挂载 ISO 文件
|
||||||
|
if mount -o loop "$source" "$temp_mount" 2>/dev/null; then
|
||||||
|
info "成功挂载 ISO 文件到: $temp_mount"
|
||||||
|
source="$temp_mount"
|
||||||
|
else
|
||||||
|
warn "无法挂载 ISO 文件,可能需要 root 权限" >&2
|
||||||
|
rmdir "$temp_mount" 2>/dev/null
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 确保目标目录存在
|
||||||
|
# 提取目标目录(如果是文件,取目录部分)
|
||||||
|
local dest_dir
|
||||||
|
if [[ "$destination" == */ ]]; then
|
||||||
|
dest_dir="$destination" # 目标 / 结尾, 视为目录
|
||||||
|
else
|
||||||
|
dest_dir="$(dirname "$destination")" # 目标是文件, 取目录部分
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ! -d "$dest_dir" ]]; then
|
||||||
|
info "创建目标目录: $dest_dir"
|
||||||
|
mkdir -p "$dest_dir" || {
|
||||||
|
warn "无法创建目标目录: $dest_dir" >&2
|
||||||
|
exit_code=1
|
||||||
|
cleanup
|
||||||
|
}
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 确保源路径以斜杠结尾(rsync 目录同步规范)
|
||||||
|
local rsync_source="$source"
|
||||||
|
if [[ -d "$source" ]]; then
|
||||||
|
# 如果是目录,确保以 / 结尾,这样同步目录内容而不是目录本身
|
||||||
|
rsync_source="${source}/"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 执行 rsync 同步
|
||||||
|
info "开始同步数据..."
|
||||||
|
info " 源路径: $source"
|
||||||
|
info " 目标路径: $destination"
|
||||||
|
info " rsync 选项: $rsync_opts"
|
||||||
|
|
||||||
|
rsync $rsync_opts "$rsync_source" "$destination"
|
||||||
|
exit_code=$?
|
||||||
|
|
||||||
|
if [[ $exit_code -eq 0 ]]; then
|
||||||
|
info "同步成功完成"
|
||||||
|
else
|
||||||
|
warn "rsync 同步失败,退出码: $exit_code" >&2
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 清理:卸载临时挂载点
|
||||||
|
cleanup() {
|
||||||
|
if [[ "$is_iso" == "true" ]] && [[ -n "$temp_mount" ]]; then
|
||||||
|
info "清理临时挂载点..."
|
||||||
|
umount "$temp_mount" 2>/dev/null || {
|
||||||
|
warn "无法卸载 $temp_mount,可能需要手动清理" >&2
|
||||||
|
}
|
||||||
|
rmdir "$temp_mount" 2>/dev/null
|
||||||
|
info "已删除临时挂载点: $temp_mount"
|
||||||
|
fi
|
||||||
|
|
||||||
|
return $exit_code
|
||||||
|
}
|
||||||
|
}
|
||||||
# ====================== 帮助文档 ======================
|
# ====================== 帮助文档 ======================
|
||||||
show_help() {
|
show_help() {
|
||||||
cat <<EOF
|
cat <<EOF
|
||||||
@@ -1173,11 +1077,10 @@ Usage: sunhpc <COMMAND> [OPTIONS]
|
|||||||
-n, --nodes <list> 指定节点(all 或 node1,node2,node3)
|
-n, --nodes <list> 指定节点(all 或 node1,node2,node3)
|
||||||
|
|
||||||
支持命令:
|
支持命令:
|
||||||
sunhpc pxe dhcp 部署dhcp服务
|
|
||||||
sunhpc pxe tftp 部署tftp服务
|
|
||||||
sunhpc pxe http 部署http服务
|
sunhpc pxe http 部署http服务
|
||||||
sunhpc pxe dnsmasq 部署pxe服务
|
sunhpc pxe dnsmasq 部署pxe服务
|
||||||
sunhpc exec 批量执行命令
|
sunhpc exec 批量执行命令
|
||||||
|
sunhpc init Execute the init op
|
||||||
sunhpc sync file 执行同步任务
|
sunhpc sync file 执行同步任务
|
||||||
sunhpc list node 查看节点列表
|
sunhpc list node 查看节点列表
|
||||||
sunhpc show vimrc 显示Vimrc变量
|
sunhpc show vimrc 显示Vimrc变量
|
||||||
@@ -1251,38 +1154,44 @@ log_debug() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# ====================== 子命令执行 ======================
|
# ====================== 子命令执行 ======================
|
||||||
run_pxe_dhcp() {
|
|
||||||
log_debug "--------- run_pxe_dhcp----------------"
|
|
||||||
log_debug "当前节点:${GLOBAL_NODES[*]}"
|
|
||||||
log_debug "公共参数:${PUBLIC_ARGS[*]}"
|
|
||||||
log_debug "私有参数:${PRIVATE_ARGS[*]}"
|
|
||||||
|
|
||||||
# -n 非空True,-z 为空True
|
|
||||||
[[ -n ${GLOBAL_OPTS[interface]} ]] && pxe_dhcp_build || \
|
|
||||||
warn "请指定DHCP监听接口命名, 例如: sunhpc pxe dhcp -i eth0"
|
|
||||||
}
|
|
||||||
run_pxe_tftp() {
|
|
||||||
log_debug "--------- run_pxe_tftp----------------"
|
|
||||||
log_debug "当前节点:${GLOBAL_NODES[*]}"
|
|
||||||
log_debug "公共参数:${PUBLIC_ARGS[*]}"
|
|
||||||
log_debug "私有参数:${PRIVATE_ARGS[*]}"
|
|
||||||
pxe_tftp_build
|
|
||||||
}
|
|
||||||
run_pxe_http() {
|
run_pxe_http() {
|
||||||
log_debug "--------- run_pxe_http----------------"
|
|
||||||
log_debug "当前节点:${GLOBAL_NODES[*]}"
|
|
||||||
log_debug "公共参数:${PUBLIC_ARGS[*]}"
|
|
||||||
log_debug "私有参数:${PRIVATE_ARGS[*]}"
|
|
||||||
pxe_http_build
|
pxe_http_build
|
||||||
}
|
}
|
||||||
|
|
||||||
run_init() {
|
run_init() {
|
||||||
|
|
||||||
[[ -n "${GLOBAL_OPTS[interface]}" ]] && iface="${GLOBAL_OPTS[interface]}" || \
|
info "初次使用此工具,需要在当前目录创建一个配置文件."
|
||||||
error "必须指定一个网络接口,例如: -i/--interface eth1"
|
info " 1、手动创建配置文件,e.g., touch $config_file"
|
||||||
|
info " 2、自动创建配置文件,e.g., "
|
||||||
|
info " sunhpc init -i <interface> -m /mnt/cdrom"
|
||||||
|
echo ""
|
||||||
|
|
||||||
[[ -n "${GLOBAL_OPTS[html]-}" ]] && html="${GLOBAL_OPTS[html]}" || \
|
getArgs interface iface e "必须指定一个网络接口,例如: -i/--interface eth1"
|
||||||
error "必须指定 html 路径,例如: --html /var/www/html"
|
getArgs mntroot mntroot e "必须指定 mnt 路径,例如: -m/--mntroot /mnt/cdrom"
|
||||||
|
|
||||||
|
treeinfo=$(find -L $mntroot -name ".treeinfo")
|
||||||
|
parse_treeinfo $treeinfo
|
||||||
|
|
||||||
|
#for key in "${!global_treeinfo[@]}"; do echo "key: '$key', Value: '${global_treeinfo[$key]}'";done
|
||||||
|
|
||||||
|
[[ -z "$treeinfo" ]] && warn "提供的 $mntroot 目录为空,或是不被支持的系统."
|
||||||
|
|
||||||
|
nopkgs=()
|
||||||
|
pkgs=("ipxe-bootimgs")
|
||||||
|
filter_pkgs pkgs nopkgs
|
||||||
|
|
||||||
|
local cmd=("dnf -y install ${nopkgs[*]}")
|
||||||
|
[[ -z ${nopkgs[@]} ]] || run_with_progress "DNF Install ipxe tools..." "$cmd" "$log_file"
|
||||||
|
|
||||||
|
srv_root="/srv"
|
||||||
|
repos_root="$srv_root/repos"
|
||||||
|
|
||||||
|
kernel_path="${global_treeinfo[images-x86_64.kernel]}"
|
||||||
|
initrd_path="${global_treeinfo[images-x86_64.initrd]}"
|
||||||
|
|
||||||
|
sys_os_rels="${global_treeinfo[general.family]}" # RockyLinux
|
||||||
|
sys_os_vers="${global_treeinfo[general.version]}" # 9.7
|
||||||
|
url_os_path="$sys_os_rels/$sys_os_vers" # http://ip/ 后面系统路径 rockylinux/9.7
|
||||||
|
|
||||||
ipaddr=${global_env[${iface}_ip]}
|
ipaddr=${global_env[${iface}_ip]}
|
||||||
netcidr=${global_env[${iface}_mask]}
|
netcidr=${global_env[${iface}_mask]}
|
||||||
@@ -1293,26 +1202,83 @@ run_init() {
|
|||||||
start_ip="$i1.$i2.$i3.10"
|
start_ip="$i1.$i2.$i3.10"
|
||||||
ender_ip="$i1.$i2.$i3.90"
|
ender_ip="$i1.$i2.$i3.90"
|
||||||
|
|
||||||
|
mnt_dst="$repos_root/$url_os_path"
|
||||||
|
rsync_sync_file $mntroot $mnt_dst
|
||||||
|
|
||||||
tmpdir=$(find -L $html -name ".treeinfo")
|
lrepo_path="$repos_root/$sys_os_rels"
|
||||||
tmpdir=$(dirname ${tmpdir#$html})
|
|
||||||
|
|
||||||
echo "iface---------> $iface"
|
wwwroot="/var/www/html/linux"
|
||||||
echo "addr----------> $ipaddr"
|
[[ -e $wwwroot ]] || mkdir -p $wwwroot
|
||||||
echo "startip-------> $start_ip"
|
|
||||||
echo "enderip-------> $ender_ip"
|
ks_src="$PWD/pkgs/"
|
||||||
echo "htmlroot------> $html"
|
ks_dst="$srv_root/htool/pkgs/"
|
||||||
echo "reporoot------> $tmpdir"
|
[[ -e $ks_src ]] && rsync_sync_file $ks_src $ks_dst
|
||||||
exit 1
|
|
||||||
|
tftpboot="/srv/pxelinux/tftpboot"
|
||||||
|
|
||||||
|
efi_src="$mnt_dst/EFI/BOOT/BOOTX64.EFI"
|
||||||
|
[[ -e $efi_src ]] && rsync_sync_file $efi_src $tftpboot/bootx64.efi \
|
||||||
|
|| warn "UEFI Boot file no found: $efi_src"
|
||||||
|
|
||||||
|
ipxe_src="/usr/share/ipxe/undionly.kpxe"
|
||||||
|
[[ -e $ipxe_src ]] && rsync_sync_file $ipxe_src $tftpboot/boot/ \
|
||||||
|
|| warn "iPXE Boot file no found: $ipxe_tools"
|
||||||
|
|
||||||
|
ks_args="net.ifnames=0 biosdevname=0"
|
||||||
|
ks_rhel="http://$ipaddr/linux/ks/rhel.ks"
|
||||||
|
ks_dfmt="http://$ipaddr/linux/ks/dfmt.sh"
|
||||||
|
ks_ipxe="http://$ipaddr/linux/ks/ipxe.sh"
|
||||||
|
ks_init="http://$ipaddr/linux/ks/init.sh"
|
||||||
|
ks_repo="http://$ipaddr/linux/$url_os_path"
|
||||||
|
vmlinuz="http://$ipaddr/linux/$url_os_path/$kernel_path"
|
||||||
|
initrds="http://$ipaddr/linux/$url_os_path/$initrd_path"
|
||||||
|
|
||||||
{
|
{
|
||||||
|
echo "# ===================================================="
|
||||||
|
echo "# Generated by htool commands"
|
||||||
|
echo "# ===================================================="
|
||||||
|
echo ""
|
||||||
echo "interface $iface"
|
echo "interface $iface"
|
||||||
echo "server $ipaddr"
|
echo "server $ipaddr"
|
||||||
echo "range $start_ip,$ender_ip"
|
echo "pkgsroot $ks_dst"
|
||||||
echo "htmlroot $html"
|
echo "wwwroot $wwwroot"
|
||||||
echo "reporoot $tmpdir"
|
echo "tftpboot $tftpboot"
|
||||||
} > ${config_file}
|
echo "startip $start_ip"
|
||||||
#gen_config_file
|
echo "endip $ender_ip"
|
||||||
|
echo "dns 223.5.5.5"
|
||||||
|
echo "osname $sys_os_rels"
|
||||||
|
echo "osvers $sys_os_vers"
|
||||||
|
echo "ospath $url_os_path"
|
||||||
|
echo "lrepo $lrepo_path"
|
||||||
|
echo "bios $tftpboot/boot/undionly.kpxe"
|
||||||
|
echo "uefi $tftpboot/boot/bootx64.efi"
|
||||||
|
echo "dfmt $ks_dfmt"
|
||||||
|
echo "ksaddr $ks_rhel"
|
||||||
|
echo "ipxeboot $ks_ipxe"
|
||||||
|
echo "repos $ks_repo"
|
||||||
|
echo "vmlinuz $vmlinuz"
|
||||||
|
echo "initrd $initrds"
|
||||||
|
} > $config_file
|
||||||
|
|
||||||
|
pkgs_ipxe="$srv_root/htool/pkgs/ks/ipxe.sh"
|
||||||
|
sed -i "s|@osname@|$sys_os_rels|" $pkgs_ipxe
|
||||||
|
sed -i "s|@osrels@|"${sys_os_rels^}"|" $pkgs_ipxe
|
||||||
|
sed -i "s|@osvers@|$sys_os_vers|" $pkgs_ipxe
|
||||||
|
sed -i "s|@vmlinuz@|$vmlinuz|" $pkgs_ipxe
|
||||||
|
sed -i "s|@initrds@|$initrds|" $pkgs_ipxe
|
||||||
|
sed -i "s|@kargs@|$ks_args|" $pkgs_ipxe
|
||||||
|
sed -i "s|@repos@|$ks_repo|" $pkgs_ipxe
|
||||||
|
sed -i "s|@ksarg@|$ks_rhel|" $pkgs_ipxe
|
||||||
|
|
||||||
|
pkgs_rhel="$srv_root/htool/pkgs/ks/rhel.ks"
|
||||||
|
sed -i "s|@url@|$ks_repo|" $pkgs_rhel
|
||||||
|
sed -i "s|@dfmt@|$ks_dfmt|" $pkgs_rhel
|
||||||
|
sed -i "s|@init@|$ks_init|" $pkgs_rhel
|
||||||
|
|
||||||
|
|
||||||
|
pkgs_init="${ks_dst}ks/init.sh"
|
||||||
|
sed -i "s|@osipaddr@|$ipaddr|" $pkgs_init
|
||||||
|
sed -i "s|@ospath@|$url_os_path|" $pkgs_init
|
||||||
}
|
}
|
||||||
|
|
||||||
run_exec() {
|
run_exec() {
|
||||||
@@ -1451,7 +1417,7 @@ create_sync_file() {
|
|||||||
dispatch() {
|
dispatch() {
|
||||||
# 优先显示帮助
|
# 优先显示帮助
|
||||||
if [[ -n "${GLOBAL_OPTS[h]}" || -n "${GLOBAL_OPTS[help]}" || ${#CMD_STACK[@]} -eq 0 ]]; then
|
if [[ -n "${GLOBAL_OPTS[h]}" || -n "${GLOBAL_OPTS[help]}" || ${#CMD_STACK[@]} -eq 0 ]]; then
|
||||||
show_help
|
[[ $helper -ne 1 ]] && show_help
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -1462,13 +1428,14 @@ dispatch() {
|
|||||||
case "${CMD_STACK[0]}" in
|
case "${CMD_STACK[0]}" in
|
||||||
pxe)
|
pxe)
|
||||||
case "${CMD_STACK[1]}" in
|
case "${CMD_STACK[1]}" in
|
||||||
dhcp) run_pxe_dhcp ;;
|
|
||||||
tftp) run_pxe_tftp;;
|
|
||||||
http) run_pxe_http;;
|
http) run_pxe_http;;
|
||||||
dnsmasq) pxe_dnsmasq_build;;
|
dnsmasq) pxe_dnsmasq_build;;
|
||||||
*) show_help;;
|
*) show_help;;
|
||||||
esac
|
esac
|
||||||
;;
|
;;
|
||||||
|
init)
|
||||||
|
run_init
|
||||||
|
;;
|
||||||
exec)
|
exec)
|
||||||
run_exec "${CMD_STACK[1]}"
|
run_exec "${CMD_STACK[1]}"
|
||||||
;;
|
;;
|
||||||
@@ -1504,7 +1471,7 @@ dispatch() {
|
|||||||
*) show_help ;;
|
*) show_help ;;
|
||||||
esac
|
esac
|
||||||
;;
|
;;
|
||||||
*) show_help ;;
|
*) [[ $helper -ne 1 ]] && show_help ;;
|
||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1517,6 +1484,8 @@ parse_args() {
|
|||||||
-v) GLOBAL_OPTS[v]=1; GLOBAL_OPTS[verbose]=1; PUBLIC_ARGS+=("$arg"); shift ;;
|
-v) GLOBAL_OPTS[v]=1; GLOBAL_OPTS[verbose]=1; PUBLIC_ARGS+=("$arg"); shift ;;
|
||||||
-d) GLOBAL_OPTS[d]=1; GLOBAL_OPTS[debug]=1; PUBLIC_ARGS+=("$arg"); shift ;;
|
-d) GLOBAL_OPTS[d]=1; GLOBAL_OPTS[debug]=1; PUBLIC_ARGS+=("$arg"); shift ;;
|
||||||
-h) GLOBAL_OPTS[h]=1; GLOBAL_OPTS[help]=1; PUBLIC_ARGS+=("$arg"); shift ;;
|
-h) GLOBAL_OPTS[h]=1; GLOBAL_OPTS[help]=1; PUBLIC_ARGS+=("$arg"); shift ;;
|
||||||
|
-m) GLOBAL_OPTS[mntroot]=$2; PUBLIC_ARGS+=("$arg" "$2"); shift 2 ;;
|
||||||
|
-w) GLOBAL_OPTS[wwwroot]=$2; PUBLIC_ARGS+=("$arg" "$2"); shift 2 ;;
|
||||||
-f) GLOBAL_OPTS[file]=$2; PUBLIC_ARGS+=("$arg" "$2"); shift 2 ;;
|
-f) GLOBAL_OPTS[file]=$2; PUBLIC_ARGS+=("$arg" "$2"); shift 2 ;;
|
||||||
-i) GLOBAL_OPTS[interface]=$2; PUBLIC_ARGS+=("$arg" "$2"); shift 2 ;;
|
-i) GLOBAL_OPTS[interface]=$2; PUBLIC_ARGS+=("$arg" "$2"); shift 2 ;;
|
||||||
-n) parse_nodes "$2"; PUBLIC_ARGS+=("$arg" "$2"); shift 2 ;;
|
-n) parse_nodes "$2"; PUBLIC_ARGS+=("$arg" "$2"); shift 2 ;;
|
||||||
@@ -1525,8 +1494,9 @@ parse_args() {
|
|||||||
--verbose) GLOBAL_OPTS[verbose]=1; GLOBAL_OPTS[v]=1; PUBLIC_ARGS+=("$arg"); shift ;;
|
--verbose) GLOBAL_OPTS[verbose]=1; GLOBAL_OPTS[v]=1; PUBLIC_ARGS+=("$arg"); shift ;;
|
||||||
--debug) GLOBAL_OPTS[debug]=1; GLOBAL_OPTS[d]=1; PUBLIC_ARGS+=("$arg"); shift ;;
|
--debug) GLOBAL_OPTS[debug]=1; GLOBAL_OPTS[d]=1; PUBLIC_ARGS+=("$arg"); shift ;;
|
||||||
--help) GLOBAL_OPTS[help]=1; GLOBAL_OPTS[h]=1; PUBLIC_ARGS+=("$arg"); shift ;;
|
--help) GLOBAL_OPTS[help]=1; GLOBAL_OPTS[h]=1; PUBLIC_ARGS+=("$arg"); shift ;;
|
||||||
|
--mntroot) GLOBAL_OPTS[mntroot]=$2; PUBLIC_ARGS+=("$arg" "$2"); shift 2 ;;
|
||||||
|
--wwwroot) GLOBAL_OPTS[wwwroot]=$2; PUBLIC_ARGS+=("$arg" "$2"); shift 2 ;;
|
||||||
--file) GLOBAL_OPTS[file]=$2; PUBLIC_ARGS+=("$arg" "$2"); shift 2 ;;
|
--file) GLOBAL_OPTS[file]=$2; PUBLIC_ARGS+=("$arg" "$2"); shift 2 ;;
|
||||||
--html) GLOBAL_OPTS[html]=$2; PUBLIC_ARGS+=("$arg" "$2"); shift 2 ;;
|
|
||||||
--interface) GLOBAL_OPTS[interface]=$2; PUBLIC_ARGS+=("$arg" "$2"); shift 2 ;;
|
--interface) GLOBAL_OPTS[interface]=$2; PUBLIC_ARGS+=("$arg" "$2"); shift 2 ;;
|
||||||
--nodes) parse_nodes "$2"; PUBLIC_ARGS+=("$arg" "$2"); shift 2 ;;
|
--nodes) parse_nodes "$2"; PUBLIC_ARGS+=("$arg" "$2"); shift 2 ;;
|
||||||
|
|
||||||
@@ -1555,15 +1525,20 @@ main() {
|
|||||||
# 默认使用文件中的节点
|
# 默认使用文件中的节点
|
||||||
GLOBAL_NODES=("${DEFAULT_NODES[@]}")
|
GLOBAL_NODES=("${DEFAULT_NODES[@]}")
|
||||||
|
|
||||||
parse_args "$@"
|
|
||||||
|
|
||||||
# 获取基础信息存储变量
|
# 获取基础信息存储变量
|
||||||
if [[ -e $config_file ]]; then
|
if [[ ! -e $config_file ]]; then
|
||||||
load_conf_envs
|
info "$DSEP"
|
||||||
else
|
warn "配置文件不存在: $config_file "
|
||||||
run_init
|
warn "首次使用此工具需要使用下面命令进行初始化操作:"
|
||||||
|
warn " sunhpc init -i eth1 -m /mnt/cdrom"
|
||||||
|
info "$DSEP"
|
||||||
|
echo ""
|
||||||
|
helper=1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
[[ -e $config_file ]] && load_conf_envs
|
||||||
|
|
||||||
|
parse_args "$@"
|
||||||
dispatch
|
dispatch
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user