debian: 支持传统安装模式 + 静态 IP

This commit is contained in:
bin456789 2024-03-16 23:06:38 +08:00
parent 8b3ba5c7d3
commit ada822deb3
No known key found for this signature in database
GPG Key ID: EE301B386DE6C11B
3 changed files with 223 additions and 88 deletions

View File

@ -1,5 +1,6 @@
#!/bin/ash #!/bin/ash
# shellcheck shell=dash # shellcheck shell=dash
# alpine / debian initrd 共用此脚本
mac_addr=$1 mac_addr=$1
ipv4_addr=$2 ipv4_addr=$2
@ -9,7 +10,8 @@ ipv6_gateway=$5
is_in_china=$6 is_in_china=$6
# 3.16-3.18 $device # 3.16-3.18 $device
# 3.19.1+ $iface # 3.19 $iface
# debian $iface
# shellcheck disable=SC2154 # shellcheck disable=SC2154
if [ -n "$iface" ]; then if [ -n "$iface" ]; then
ethx="$iface" ethx="$iface"
@ -30,7 +32,12 @@ else
fi fi
get_first_ipv4_addr() { get_first_ipv4_addr() {
ip -4 -o addr show scope global dev "$ethx" | head -1 | awk '{print $4}' # debian 11 initrd 没有 awk
if false; then
ip -4 -o addr show scope global dev "$ethx" | head -1 | awk '{print $4}'
else
ip -4 -o addr show scope global dev "$ethx" | head -1 | grep -o '[0-9\.]*/[0-9]*'
fi
} }
is_have_ipv4_addr() { is_have_ipv4_addr() {
@ -120,12 +127,13 @@ is_need_test_ipv6() {
test_internet() { test_internet() {
echo 'Testing Internet Connection...' echo 'Testing Internet Connection...'
# debian 没有 nslookup因此用 ping
for i in $(seq 5); do for i in $(seq 5); do
if is_need_test_ipv4 && nslookup www.qq.com $ipv4_dns1 >/dev/null 2>&1; then if is_need_test_ipv4 && ping -c1 -W5 $ipv4_dns1 >/dev/null 2>&1; then
echo "IPv4 has internet." echo "IPv4 has internet."
ipv4_has_internet=true ipv4_has_internet=true
fi fi
if is_need_test_ipv6 && nslookup www.qq.com $ipv6_dns1 >/dev/null 2>&1; then if is_need_test_ipv6 && ping -c1 -W5 $ipv6_dns1 >/dev/null 2>&1; then
echo "IPv6 has internet." echo "IPv6 has internet."
ipv6_has_internet=true ipv6_has_internet=true
fi fi

View File

@ -1368,22 +1368,96 @@ mkdir_clear() {
mkdir -p $dir mkdir -p $dir
} }
mod_alpine_initrd() { mod_initrd_debian() {
# 修改 alpine 启动时运行我们的脚本 # hack 1
info mod alpine initrd # 允许设置 ipv4 onlink 网关
install_pkg gzip cpio sed -Ei 's,&&( onlink=),||\1,' etc/udhcpc/default.script
# 解压 # hack 2
# 先删除临时文件,避免之前运行中断有残留文件 # 修改 /var/lib/dpkg/info/netcfg.postinst 运行我们的脚本
tmp_dir=/tmp/reinstall # shellcheck disable=SC1091,SC2317
mkdir_clear $tmp_dir netcfg() {
cd $tmp_dir #!/bin/sh
zcat /reinstall-initrd | cpio -idm . /usr/share/debconf/confmodule
db_progress START 0 5 debian-installer/netcfg/title
# 预先下载脚本 # 找到主网卡
curl -Lo $tmp_dir/trans.start $confhome/trans.sh # debian 11 initrd 没有 awk
curl -Lo $tmp_dir/alpine-network.sh $confhome/alpine-network.sh if false; then
iface=$(ip -o link | grep "@mac_addr" | awk '{print $2}' | cut -d: -f1)
else
iface=$(ip -o link | grep "@mac_addr" | cut -d' ' -f2 | cut -d: -f1)
fi
db_progress STEP 1
# dhcpv4
db_progress INFO netcfg/dhcp_progress
udhcpc -i "$iface" -f -q -n
db_progress STEP 1
# slaac + dhcpv6
db_progress INFO netcfg/slaac_wait_title
# https://salsa.debian.org/installer-team/netcfg/-/blob/master/autoconfig.c#L148
cat <<EOF >/var/lib/netcfg/dhcp6c.conf
interface $iface {
send ia-na 0;
request domain-name-servers;
request domain-name;
script "/lib/netcfg/print-dhcp6c-info";
};
id-assoc na 0 {
};
EOF
dhcp6c -c /var/lib/netcfg/dhcp6c.conf "$iface"
sleep 10
kill -9 "$(cat /var/run/dhcp6c.pid)"
db_progress STEP 1
# 静态 + 检测网络
db_subst netcfg/link_detect_progress interface "$iface"
db_progress INFO netcfg/link_detect_progress
. /alpine-network.sh @netconf
db_progress STEP 1
# 运行trans.sh保存配置
db_progress INFO base-installer/progress/netcfg
. /trans.sh
db_progress STEP 1
}
collect_netconf
is_in_china && is_in_china=true || is_in_china=false
netconf="'$mac_addr' '$ipv4_addr' '$ipv4_gateway' '$ipv6_addr' '$ipv6_gateway' '$is_in_china'"
get_function_content netcfg |
sed "s|@mac_addr|$mac_addr|" |
sed "s|@netconf|$netconf|" >var/lib/dpkg/info/netcfg.postinst
# hack 3
# 修改 trans.sh
# 1. 直接调用 create_ifupdown_config
insert_into_file $tmp_dir/trans.sh after ': main' <<EOF
distro=debian
create_ifupdown_config /etc/network/interfaces
exit
EOF
# 2. 删除 debian busybox 无法识别的语法
# 3. 删除 apk 语句
# 4. debian 11/12 initrd 无法识别 > >
# 5. debian 11/12 initrd 无法识别 < <
# 6. debian 11 initrd 无法识别 set -E
# 7. debian 11 initrd 无法识别 trap ERR
# 删除或注释,可能会导致空方法而报错,因此改为替换成'\n: #'
replace='\n: #'
sed -Ei "s/> >/$replace/" $tmp_dir/trans.sh
sed -Ei "s/< </$replace/" $tmp_dir/trans.sh
sed -Ei "s/(^[[:space:]]*set[[:space:]].*)E/\1/" $tmp_dir/trans.sh
sed -Ei "s/^[[:space:]]*apk[[:space:]]/$replace/" $tmp_dir/trans.sh
sed -Ei "s/^[[:space:]]*trap[[:space:]]/$replace/" $tmp_dir/trans.sh
}
mod_initrd_alpine() {
# virt 内核添加 ipv6 模块 # virt 内核添加 ipv6 模块
if virt_dir=$(ls -d $tmp_dir/lib/modules/*-virt 2>/dev/null); then if virt_dir=$(ls -d $tmp_dir/lib/modules/*-virt 2>/dev/null); then
ipv6_dir=$virt_dir/kernel/net/ipv6 ipv6_dir=$virt_dir/kernel/net/ipv6
@ -1410,13 +1484,14 @@ EOF
# hack 2 设置 ethx # hack 2 设置 ethx
# 3.16~3.18 ip_choose_if # 3.16~3.18 ip_choose_if
# 3.19.1+ ethernets # 3.19 ethernets
if grep -q ip_choose_if init; then if grep -q ip_choose_if init; then
ethernets_func=ip_choose_if ethernets_func=ip_choose_if
else else
ethernets_func=ethernets ethernets_func=ethernets
fi fi
# shellcheck disable=SC2317
ip_choose_if() { ip_choose_if() {
ip -o link | grep "@mac_addr" | awk '{print $2}' | cut -d: -f1 ip -o link | grep "@mac_addr" | awk '{print $2}' | cut -d: -f1
return return
@ -1431,7 +1506,7 @@ EOF
# 使用同样参数运行 udhcpc6 # 使用同样参数运行 udhcpc6
# udhcpc -i "$device" -f -q # v3.17 # udhcpc -i "$device" -f -q # v3.17
# $MOCK udhcpc -i "$device" -f -q # v3.18 # $MOCK udhcpc -i "$device" -f -q # v3.18
# $MOCK udhcpc -i "$iface" -f -q # v3.19.1 # $MOCK udhcpc -i "$iface" -f -q # v3.19
search='udhcpc -i' search='udhcpc -i'
orig_cmd="$(grep "$search" init)" orig_cmd="$(grep "$search" init)"
mod_cmd4="$orig_cmd -n || true" mod_cmd4="$orig_cmd -n || true"
@ -1444,12 +1519,13 @@ EOF
# udhcpc: bound # udhcpc: bound
# udhcpc6: deconfig # udhcpc6: deconfig
# udhcpc6: bound # udhcpc6: bound
# shellcheck disable=SC2154 # shellcheck disable=SC2317
udhcpc() { udhcpc() {
if [ "$1" = deconfig ]; then if [ "$1" = deconfig ]; then
return return
fi fi
if [ "$1" = bound ] && [ -n "$ipv6" ]; then if [ "$1" = bound ] && [ -n "$ipv6" ]; then
# shellcheck disable=SC2154
ip -6 addr add "$ipv6" dev "$interface" ip -6 addr add "$ipv6" dev "$interface"
ip link set dev "$interface" up ip link set dev "$interface" up
return return
@ -1465,7 +1541,7 @@ EOF
# hack 5 网络配置 # hack 5 网络配置
is_in_china && is_in_china=true || is_in_china=false is_in_china && is_in_china=true || is_in_china=false
insert_into_file init after 'MAC_ADDRESS=' <<EOF insert_into_file init after 'MAC_ADDRESS=' <<EOF
source /alpine-network.sh \ . /alpine-network.sh \
"$mac_addr" "$ipv4_addr" "$ipv4_gateway" "$ipv6_addr" "$ipv6_gateway" "$is_in_china" "$mac_addr" "$ipv4_addr" "$ipv4_gateway" "$ipv6_addr" "$ipv6_gateway" "$is_in_china"
EOF EOF
@ -1481,10 +1557,27 @@ EOF
insert_into_file init before '^exec (/bin/busybox )?switch_root' <<EOF insert_into_file init before '^exec (/bin/busybox )?switch_root' <<EOF
# echo "wget --no-check-certificate -O- $confhome/trans.sh | /bin/ash" >\$sysroot/etc/local.d/trans.start # echo "wget --no-check-certificate -O- $confhome/trans.sh | /bin/ash" >\$sysroot/etc/local.d/trans.start
# wget --no-check-certificate -O \$sysroot/etc/local.d/trans.start $confhome/trans.sh # wget --no-check-certificate -O \$sysroot/etc/local.d/trans.start $confhome/trans.sh
cp /trans.start \$sysroot/etc/local.d/trans.start cp /trans.sh \$sysroot/etc/local.d/trans.start
chmod a+x \$sysroot/etc/local.d/trans.start chmod a+x \$sysroot/etc/local.d/trans.start
ln -s /etc/init.d/local \$sysroot/etc/runlevels/default/ ln -s /etc/init.d/local \$sysroot/etc/runlevels/default/
EOF EOF
}
mod_initrd() {
info "mod $nextos_distro initrd"
install_pkg gzip cpio
# 解压
# 先删除临时文件,避免之前运行中断有残留文件
tmp_dir=/tmp/reinstall
mkdir_clear $tmp_dir
cd $tmp_dir
zcat /reinstall-initrd | cpio -idm
curl -Lo $tmp_dir/trans.sh $confhome/trans.sh
curl -Lo $tmp_dir/alpine-network.sh $confhome/alpine-network.sh
mod_initrd_$nextos_distro
# 重建 # 重建
# 注意要用 cpio -H newc 不要用 cpio -c ,不同版本的 -c 作用不一样,很坑 # 注意要用 cpio -H newc 不要用 cpio -c ,不同版本的 -c 作用不一样,很坑
@ -1702,9 +1795,9 @@ else
curl -Lo /reinstall-initrd $nextos_initrd curl -Lo /reinstall-initrd $nextos_initrd
fi fi
# 修改 alpine initrd # 修改 alpine debian initrd
if [ "$nextos_distro" = alpine ]; then if [ "$nextos_distro" = alpine ] || [ "$nextos_distro" = debian ]; then
mod_alpine_initrd mod_initrd
fi fi
# 将内核/netboot.xyz.lkrn 放到正确的位置 # 将内核/netboot.xyz.lkrn 放到正确的位置

160
trans.sh
View File

@ -376,10 +376,11 @@ get_netconf_to() {
esac esac
# shellcheck disable=SC2154 # shellcheck disable=SC2154
# debian initrd 没有 xargs
case "$1" in case "$1" in
slaac) echo "$ra" | grep 'Autonomous address conf' | grep Yes && res=1 || res=0 ;; slaac) echo "$ra" | grep 'Autonomous address conf' | grep Yes && res=1 || res=0 ;;
dhcpv6) echo "$ra" | grep 'Stateful address conf' | grep Yes && res=1 || res=0 ;; dhcpv6) echo "$ra" | grep 'Stateful address conf' | grep Yes && res=1 || res=0 ;;
rdnss) res=$(echo "$ra" | grep 'Recursive DNS server' | cut -d: -f2- | xargs) ;; rdnss) res=$(echo "$ra" | grep 'Recursive DNS server' | cut -d: -f2-) ;;
other) echo "$ra" | grep 'Stateful other conf' | grep Yes && res=1 || res=0 ;; other) echo "$ra" | grep 'Stateful other conf' | grep Yes && res=1 || res=0 ;;
*) res=$(cat /dev/$1) ;; *) res=$(cat /dev/$1) ;;
esac esac
@ -485,11 +486,21 @@ is_need_manual_set_dnsv6() {
} }
get_current_dns_v4() { get_current_dns_v4() {
grep '^nameserver' /etc/resolv.conf | awk '{print $2}' | grep '\.' # debian 11 initrd 没有 awk
if false; then
grep '^nameserver' /etc/resolv.conf | awk '{print $2}' | grep '\.'
else
grep '^nameserver' /etc/resolv.conf | cut -d' ' -f2 | grep '\.'
fi
} }
get_current_dns_v6() { get_current_dns_v6() {
grep '^nameserver' /etc/resolv.conf | awk '{print $2}' | grep ':' # debian 11 initrd 没有 awk
if false; then
grep '^nameserver' /etc/resolv.conf | awk '{print $2}' | grep ':'
else
grep '^nameserver' /etc/resolv.conf | cut -d' ' -f2 | grep ':'
fi
} }
to_upper() { to_upper() {
@ -612,6 +623,83 @@ insert_into_file() {
fi fi
} }
create_ifupdown_config() {
conf_file=$1
rm -f $conf_file
# shellcheck disable=SC2154
if [ "$distro" = debian ]; then
cat <<EOF >>$conf_file
source /etc/network/interfaces.d/*
EOF
fi
# 生成 lo配置 + ethx头部
get_netconf_to ethx
if [ -f /etc/network/devhotplug ] && grep -wo "$ethx" /etc/network/devhotplug; then
mode=allow-hotplug
else
mode=auto
fi
cat <<EOF >>$conf_file
auto lo
iface lo inet loopback
$mode $ethx
EOF
# ipv4
if is_dhcpv4; then
echo "iface $ethx inet dhcp" >>$conf_file
elif is_staticv4; then
get_netconf_to ipv4_addr
get_netconf_to ipv4_gateway
cat <<EOF >>$conf_file
iface $ethx inet static
address $ipv4_addr
gateway $ipv4_gateway
EOF
# dns
if list=$(get_current_dns_v4); then
for dns in $list; do
cat <<EOF >>$conf_file
dns-nameservers $dns
EOF
done
fi
fi
# ipv6
if is_slaac; then
echo "iface $ethx inet6 auto" >>$conf_file
elif is_dhcpv6; then
echo "iface $ethx inet6 dhcp" >>$conf_file
elif is_staticv6; then
get_netconf_to ipv6_addr
get_netconf_to ipv6_gateway
cat <<EOF >>$conf_file
iface $ethx inet6 static
address $ipv6_addr
gateway $ipv6_gateway
EOF
fi
# dns
# 有 ipv6 但需设置 dns 的情况
if is_need_manual_set_dnsv6 && list=$(get_current_dns_v6); then
for dns in $list; do
cat <<EOF >>$conf_file
dns-nameserver $dns
EOF
done
fi
}
install_alpine() { install_alpine() {
hack_lowram_modloop=true hack_lowram_modloop=true
hack_lowram_swap=true hack_lowram_swap=true
@ -675,66 +763,8 @@ install_alpine() {
sed -i '/^#slaac hwaddr/s/^#//' /etc/dhcpcd.conf sed -i '/^#slaac hwaddr/s/^#//' /etc/dhcpcd.conf
rc-update add networking boot rc-update add networking boot
get_netconf_to ethx # 网络配置
create_ifupdown_config /etc/network/interfaces
# 生成 lo配置 + ethx头部
cat <<EOF >/etc/network/interfaces
auto lo
iface lo inet loopback
auto $ethx
EOF
# ipv4
if is_dhcpv4; then
echo "iface $ethx inet dhcp" >>/etc/network/interfaces
elif is_staticv4; then
get_netconf_to ipv4_addr
get_netconf_to ipv4_gateway
cat <<EOF >>/etc/network/interfaces
iface $ethx inet static
address $ipv4_addr
gateway $ipv4_gateway
EOF
# dns
if list=$(get_current_dns_v4); then
for dns in $list; do
cat <<EOF >>/etc/network/interfaces
dns-nameserver $dns
EOF
done
fi
fi
# ipv6
if is_slaac; then
echo "iface $ethx inet6 auto" >>/etc/network/interfaces
elif is_dhcpv6; then
echo "iface $ethx inet6 dhcp" >>/etc/network/interfaces
elif is_staticv6; then
get_netconf_to ipv6_addr
get_netconf_to ipv6_gateway
cat <<EOF >>/etc/network/interfaces
iface $ethx inet6 static
address $ipv6_addr
gateway $ipv6_gateway
EOF
fi
# dns
# 有 ipv6 但需设置 dns 的情况
if is_need_manual_set_dnsv6 && list=$(get_current_dns_v6); then
for dns in $list; do
cat <<EOF >>/etc/network/interfaces
dns-nameserver $dns
EOF
done
fi
# 显示网络配置
echo echo
cat -n /etc/network/interfaces cat -n /etc/network/interfaces
echo echo
@ -2504,6 +2534,10 @@ EOF
} }
# 脚本入口 # 脚本入口
# debian initrd 会寻找 : main
# 并调用本文件的 create_ifupdown_config 方法
: main
# arm要手动从硬件同步时间避免访问https出错 # arm要手动从硬件同步时间避免访问https出错
# do 机器第二次运行会报错 # do 机器第二次运行会报错
hwclock -s || true hwclock -s || true