core: 不使用 cloud-init 初始化系统

This commit is contained in:
bin456789 2025-01-10 00:43:26 +08:00
parent abdbf03eb0
commit 4149cf2e6e
No known key found for this signature in database
GPG Key ID: EE301B386DE6C11B
7 changed files with 770 additions and 124 deletions

View File

@ -2,6 +2,23 @@
# 修复 cloud-init 没有正确渲染 onlink 网关 # 修复 cloud-init 没有正确渲染 onlink 网关
set -eE set -eE
os_dir=$1
# 该脚本也会在 alpine live 下调用
# 防止在 alpine live 下运行 systemctl netplan 报错
systemctl() {
if systemd-detect-virt --chroot; then
return
fi
command systemctl "$@"
}
netplan() {
if systemd-detect-virt --chroot; then
return
fi
command netplan "$@"
}
insert_into_file() { insert_into_file() {
file=$1 file=$1
@ -44,24 +61,24 @@ fix_netplan_conf() {
# - to: ::/0 # - to: ::/0
# via: ::1 # via: ::1
# on-link: true # on-link: true
conf=/etc/netplan/50-cloud-init.yaml conf=$os_dir/etc/netplan/50-cloud-init.yaml
if ! [ -f $conf ]; then if ! [ -f "$conf" ]; then
return return
fi fi
# 判断 bug 是否已经修复 # 判断 bug 是否已经修复
if grep 'on-link:' "$conf"; then if grep -q 'on-link:' "$conf"; then
return return
fi fi
# 获取网关 # 获取网关
gateways=$(grep 'gateway[4|6]:' $conf | awk '{print $2}') gateways=$(grep 'gateway[4|6]:' "$conf" | awk '{print $2}')
if [ -z "$gateways" ]; then if [ -z "$gateways" ]; then
return return
fi fi
# 获取缩进 # 获取缩进
spaces=$(grep 'gateway[4|6]:' $conf | head -1 | grep -o '^[[:space:]]*') spaces=$(grep 'gateway[4|6]:' "$conf" | head -1 | grep -o '^[[:space:]]*')
{ {
# 网关头部 # 网关头部
@ -82,14 +99,14 @@ ${spaces} via: $gateway
${spaces} on-link: true ${spaces} on-link: true
EOF EOF
done done
} | insert_into_file $conf before 'match:' } | insert_into_file "$conf" before 'match:'
# 删除原来的条目 # 删除原来的条目
sed -i '/gateway[4|6]:/d' $conf sed -i '/gateway[4|6]:/d' "$conf"
# 重新应用配置 # 重新应用配置
if command -v netplan && { if command -v netplan && {
systemctl is-enabled systemd-networkd || systemctl is-enabled NetworkManager systemctl -q is-enabled systemd-networkd || systemctl -q is-enabled NetworkManager
}; then }; then
netplan apply netplan apply
fi fi
@ -117,13 +134,13 @@ fix_networkd_conf() {
# Gateway=2602::1 # Gateway=2602::1
# GatewayOnLink=yes # GatewayOnLink=yes
if ! confs=$(ls /etc/systemd/network/10-cloud-init-*.network 2>/dev/null); then if ! confs=$(ls "$os_dir"/etc/systemd/network/10-cloud-init-*.network 2>/dev/null); then
return return
fi fi
for conf in $confs; do for conf in $confs; do
# 判断 bug 是否已经修复 # 判断 bug 是否已经修复
if grep '^GatewayOnLink=' "$conf"; then if grep -q '^GatewayOnLink=' "$conf"; then
return return
fi fi
@ -148,7 +165,7 @@ GatewayOnLink=yes
# 重新应用配置 # 重新应用配置
# networkctl reload 不起作用 # networkctl reload 不起作用
if systemctl is-enabled systemd-networkd; then if systemctl -q is-enabled systemd-networkd; then
systemctl restart systemd-networkd systemctl restart systemd-networkd
fi fi
} }
@ -166,13 +183,13 @@ fix_wicked_conf() {
# default 1.1.1.1 - - # default 1.1.1.1 - -
# default 2602::1 - - # default 2602::1 - -
if ! confs=$(ls /etc/sysconfig/network/ifroute-* 2>/dev/null); then if ! confs=$(ls "$os_dir/etc/sysconfig/network/ifroute-"* 2>/dev/null); then
return return
fi fi
for conf in $confs; do for conf in $confs; do
# 判断 bug 是否已经修复 # 判断 bug 是否已经修复
if grep -v 'default' "$conf" | grep '-'; then if grep -v 'default' "$conf" | grep -q '-'; then
return return
fi fi
@ -189,7 +206,7 @@ fix_wicked_conf() {
done done
# 重新应用配置 # 重新应用配置
if systemctl is-enabled wicked; then if systemctl -q is-enabled wicked; then
systemctl restart wicked systemctl restart wicked
fi fi
} }

View File

@ -177,4 +177,8 @@ d-i preseed/late_command string true; \
if [ -n "$ssh_port" ] && ! [ "$ssh_port" = 22 ]; then \ if [ -n "$ssh_port" ] && ! [ "$ssh_port" = 22 ]; then \
echo "Port $ssh_port" >/target/etc/ssh/sshd_config.d/01-change-ssh-port.conf || \ echo "Port $ssh_port" >/target/etc/ssh/sshd_config.d/01-change-ssh-port.conf || \
echo "Port $ssh_port" >>/target/etc/ssh/sshd_config; \ echo "Port $ssh_port" >>/target/etc/ssh/sshd_config; \
fi fi; \
cp /fix-eth-name.sh /target/; \
cp /fix-eth-name.service /target/etc/systemd/system/; \
in-target systemctl enable fix-eth-name

26
fix-eth-name.initd Normal file
View File

@ -0,0 +1,26 @@
#!/sbin/openrc-run
Description="Fix Eth Name"
# https://gitlab.alpinelinux.org/alpine/aports/-/blob/master/main/openrc/networking.initd
# https://gitlab.alpinelinux.org/alpine/aports/-/blob/master/main/dhcpcd/dhcpcd.initd
depend() {
need localmount
want dev-settle
after bootmisc hwdrivers modules
before net networking dhcpcd
}
start() {
ebegin "Fix Eth Name"
ash /fix-eth-name.sh
eend $?
}
start_post() {
rc-service fix-eth-name zap
rc-update del fix-eth-name boot
rm -f /etc/init.d/fix-eth-name
rm -f /fix-eth-name.sh
}

27
fix-eth-name.service Normal file
View File

@ -0,0 +1,27 @@
[Unit]
Description=Fix Eth Name
ConditionPathExists=/fix-eth-name.sh
After=dbus.service
Before=cloud-init-local.service
Before=network.service
Before=networking.service
Before=systemd-networkd.service
Before=NetworkManager.service
Before=wickedd-auto4.service
Before=wickedd-dhcp4.service
Before=wickedd-dhcp6.service
Before=wickedd.service
Before=network.target
[Service]
Type=oneshot
ExecStart=/usr/bin/env bash /fix-eth-name.sh
ExecStart=/usr/bin/env rm -f /fix-eth-name.sh
ExecStart=/usr/bin/env rm -f /etc/systemd/system/fix-eth-name.service
ExecStart=/usr/bin/env rm -f /etc/systemd/system/multi-user.target.wants/fix-eth-name.service
[Install]
WantedBy=multi-user.target

239
fix-eth-name.sh Normal file
View File

@ -0,0 +1,239 @@
#!/usr/bin/env bash
# shellcheck shell=dash
# shellcheck disable=SC3001,SC3010
# alpine 使用 busybox ash
set -eE
# 本脚本在首次进入新系统后运行
# 将 trans 阶段生成的网络配置中的网卡名(eth0) 改为正确的网卡名,也适用于以下情况
# 1. alpine 要运行此脚本,因为安装后的内核可能有 netboot 没有的驱动
# 2. dmit debian 普通内核(安装时)和云内核网卡名不一致
# https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=928923
# todo: 删除 cloud-init
to_lower() {
tr '[:upper:]' '[:lower:]'
}
retry() {
local max_try=$1
local interval=$2
shift 2
for i in $(seq "$max_try"); do
if "$@"; then
return
else
ret=$?
if [ "$i" -ge "$max_try" ]; then
return $ret
fi
sleep "$interval"
fi
done
}
# openeuler 本脚本运行一秒后才有 enp3s0
# 用 systemd-analyze plot >a.svg 发现 sys-subsystem-net-devices-enp3s0.device 也是出现在 NetworkManager 之后
# 因此需要等待网卡出现
get_ethx_by_mac() {
mac=$(echo "$1" | to_lower)
retry 10 0.5 _get_ethx_by_mac "$mac"
}
_get_ethx_by_mac() {
if true; then
# 过滤 azure vf (带 master ethx)
ip -o link | grep -i "$mac" | grep -v master | awk '{print $2}' | cut -d: -f1 | grep .
return
else
for i in $(cd /sys/class/net && echo *); do
if [ "$(cat "/sys/class/net/$i/address")" = "$mac" ]; then
echo "$i"
return
fi
done
return 1
fi
}
fix_rh_sysconfig() {
for file in /etc/sysconfig/network-scripts/ifcfg-eth*; do
# 没有 ifcfg-eth* 也会执行一次,因此要判断文件是否存在
[ -f "$file" ] || continue
mac=$(grep ^HWADDR= "$file" | cut -d= -f2 | grep .) || continue
ethx=$(get_ethx_by_mac "$mac") || continue
proper_file=/etc/sysconfig/network-scripts/ifcfg-$ethx
if [ "$file" != "$proper_file" ]; then
# 更改文件内容
sed -i "s/^DEVICE=.*/DEVICE=$ethx/" "$file"
# 不要直接更改文件名,因为可能覆盖已有文件
mv "$file" "$proper_file.tmp"
fi
done
# 更改文件名
for tmp_file in /etc/sysconfig/network-scripts/ifcfg-e*.tmp; do
if [ -f "$tmp_file" ]; then
mv "$tmp_file" "${tmp_file%.tmp}"
fi
done
}
fix_suse_sysconfig() {
for file in /etc/sysconfig/network/ifcfg-eth*; do
[ -f "$file" ] || continue
# 可能两边有引号
mac=$(grep ^LLADDR= "$file" | cut -d= -f2 | sed "s/'//g" | grep .) || continue
ethx=$(get_ethx_by_mac "$mac") || continue
old_ethx=${file##*-}
if ! [ "$old_ethx" = "$ethx" ]; then
# 不要直接更改文件名,因为可能覆盖已有文件
for type in ifcfg ifroute; do
old_file=/etc/sysconfig/network/$type-$old_ethx
new_file=/etc/sysconfig/network/$type-$ethx.tmp
# 防止没有 ifroute-eth* 导致中断脚本
if [ -f "$old_file" ]; then
mv "$old_file" "$new_file"
fi
done
fi
done
# 上面的循环结束后,再将 tmp 改成正式文件
for tmp_file in \
/etc/sysconfig/network/ifcfg-e*.tmp \
/etc/sysconfig/network/ifroute-e*.tmp; do
if [ -f "$tmp_file" ]; then
mv "$tmp_file" "${tmp_file%.tmp}"
fi
done
}
fix_network_manager() {
for file in /etc/NetworkManager/system-connections/cloud-init-eth*.nmconnection; do
[ -f "$file" ] || continue
mac=$(grep ^mac-address= "$file" | cut -d= -f2 | grep .) || continue
ethx=$(get_ethx_by_mac "$mac") || continue
proper_file=/etc/NetworkManager/system-connections/$ethx.nmconnection
# 更改文件内容
sed -i "s/^id=.*/id=$ethx/" "$file"
# 更改文件名
mv "$file" "$proper_file"
done
}
# auto lo
# iface lo inet loopback
# # mac 11:22:33:44:55:66 # 用此行匹配网卡
# auto eth0
# iface eth0 inet static
# address 1.1.1.1/25
# gateway 1.1.1.1
# dns-nameservers 1.1.1.1
# dns-nameservers 8.8.8.8
# iface eth0 inet6 static
# address 2602:1:0:80::100/64
# gateway 2602:1:0:80::1
# dns-nameserver 2606:4700:4700::1111
# dns-nameserver 2001:4860:4860::8888
fix_ifupdown() {
file=/etc/network/interfaces
tmp_file=$file.tmp
rm -f "$tmp_file"
if [ -f "$file" ]; then
while IFS= read -r line; do
del_this_line=false
if [[ "$line" = "# mac "* ]]; then
ethx=
if mac=$(echo "$line" | awk '{print $NF}'); then
ethx=$(get_ethx_by_mac "$mac") || true
fi
del_this_line=true
elif [[ "$line" = "iface e"* ]] ||
[[ "$line" = "auto e"* ]] ||
[[ "$line" = "allow-hotplug e"* ]]; then
if [ -n "$ethx" ]; then
line=$(echo "$line" | awk "{\$2=\"$ethx\"; print \$0}")
fi
fi
if ! $del_this_line; then
echo "$line" >>"$tmp_file"
fi
done <"$file"
mv "$tmp_file" "$file"
fi
}
fix_netplan() {
file=/etc/netplan/50-cloud-init.yaml
tmp_file=$file.tmp
rm -f "$tmp_file"
if [ -f "$file" ]; then
while IFS= read -r line; do
if echo "$line" | grep -Eq '^[[:space:]]+macaddress:'; then
# 得到正确的网卡名
mac=$(echo "$line" | awk '{print $NF}' | sed 's/"//g')
ethx=$(get_ethx_by_mac "$mac") || true
elif echo "$line" | grep -Eq '^[[:space:]]+eth[0-9]+:'; then
# 改成正确的网卡名
if [ -n "$ethx" ]; then
line=$(echo "$line" | sed -E "s/[^[:space:]]+/$ethx:/")
fi
fi
echo "$line" >>"$tmp_file"
# 删除 set-name 不过这一步在 trans 已完成
# 因为 netplan-generator 会在 systemd generator 阶段就根据 netplan 配置重命名网卡
# systemd generator 阶段比本脚本和 systemd-networkd 更早运行
# 倒序
done < <(grep -Ev "^[[:space:]]+set-name:" "$file" | tac)
# 再倒序回来
tac "$tmp_file" >"$file"
rm -f "$tmp_file"
# 通过 systemd netplan generator 生成 /run/systemd/network/10-netplan-enp3s0.network
systemctl daemon-reload
fi
}
fix_systemd_networkd() {
for file in /etc/systemd/network/10-cloud-init-eth*.network; do
[ -f "$file" ] || continue
mac=$(grep ^MACAddress= $file | cut -d= -f2 | grep .) || continue
ethx=$(get_ethx_by_mac "$mac") || continue
proper_file=/etc/systemd/network/10-$ethx.network
# 更改文件内容
sed -Ei "s/^Name=eth[0-9]+/Name=$ethx/" "$file"
# 更改文件名
mv "$file" "$proper_file"
done
}
fix_rh_sysconfig
fix_suse_sysconfig
fix_network_manager
fix_ifupdown
fix_netplan
fix_systemd_networkd

View File

@ -1059,8 +1059,17 @@ setos() {
# debian --ci 用此标记要是否要换 elts 源 # debian --ci 用此标记要是否要换 elts 源
# shellcheck disable=SC2034 # shellcheck disable=SC2034
is_debian_elts && elts=1 || elts=0 is_debian_elts && elts=1 || elts=0
is_virt && ci_type=genericcloud || ci_type=generic
# https://salsa.debian.org/cloud-team/debian-cloud-images/-/tree/master/config_space/bookworm/files/etc/default/grub.d
# cloud 包括各种奇怪的优化,例如不显示 grub 菜单
# 因此使用 nocloud
if false; then
is_virt && ci_type=genericcloud || ci_type=generic
else
ci_type=nocloud
fi
eval ${step}_img=$cdimage_mirror/cloud/$codename/latest/debian-$releasever-$ci_type-$basearch_alt.qcow2 eval ${step}_img=$cdimage_mirror/cloud/$codename/latest/debian-$releasever-$ci_type-$basearch_alt.qcow2
eval ${step}_kernel=linux-image$flavour-$basearch_alt
else else
# 传统安装 # 传统安装
if is_debian_elts; then if is_debian_elts; then
@ -2976,6 +2985,10 @@ EOF
# 在 debian installer 中判断能否用云内核 # 在 debian installer 中判断能否用云内核
create_can_use_cloud_kernel_sh can_use_cloud_kernel.sh create_can_use_cloud_kernel_sh can_use_cloud_kernel.sh
# 下载 fix-eth-name 脚本
curl -LO "$confhome/fix-eth-name.sh"
curl -LO "$confhome/fix-eth-name.service"
# 最近 kali initrd 删除了原版 wget # 最近 kali initrd 删除了原版 wget
# 但 initrd 的 busybox wget 又不支持 https # 但 initrd 的 busybox wget 又不支持 https
# 因此改成在这里下载 # 因此改成在这里下载

536
trans.sh
View File

@ -879,15 +879,14 @@ EOF
# ethx # ethx
for ethx in $(get_eths); do for ethx in $(get_eths); do
mode=auto mode=auto
enpx=
if is_distro_like_debian; then if is_distro_like_debian; then
if [ -f /etc/network/devhotplug ] && grep -wo "$ethx" /etc/network/devhotplug; then if [ -f /etc/network/devhotplug ] && grep -wo "$ethx" /etc/network/devhotplug; then
mode=allow-hotplug mode=allow-hotplug
fi fi
if is_have_cmd udevadm; then # if is_have_cmd udevadm; then
enpx=$(udevadm test-builtin net_id /sys/class/net/$ethx 2>&1 | grep ID_NET_NAME_PATH= | cut -d= -f2) # enpx=$(udevadm test-builtin net_id /sys/class/net/$ethx 2>&1 | grep ID_NET_NAME_PATH= | cut -d= -f2)
fi # fi
fi fi
# dmit debian 普通内核和云内核网卡名不一致,因此需要 rename # dmit debian 普通内核和云内核网卡名不一致,因此需要 rename
@ -897,11 +896,12 @@ EOF
# https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=928923 # https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=928923
# 头部 # 头部
get_netconf_to mac_addr
{ {
echo echo
if [ -n "$enpx" ] && [ "$enpx" != "$ethx" ]; then # 这是标记fix-eth-name 要用,不要删除
echo rename $enpx=$ethx # shellcheck disable=SC2154
fi echo "# mac $mac_addr"
echo $mode $ethx echo $mode $ethx
} >>$conf_file } >>$conf_file
@ -1256,6 +1256,12 @@ install_alpine() {
chroot /os setup-timezone -i Asia/Shanghai chroot /os setup-timezone -i Asia/Shanghai
chroot /os setup-ntp chrony || true chroot /os setup-ntp chrony || true
# 下载 fix-eth-name
download "$confhome/fix-eth-name.sh" /os/fix-eth-name.sh
download "$confhome/fix-eth-name.initd" /os/etc/init.d/fix-eth-name
chmod +x /os/etc/init.d/fix-eth-name
chroot /os rc-update add fix-eth-name boot
# 安装固件微码会触发 grub-probe # 安装固件微码会触发 grub-probe
# 如果没挂载会报错 # 如果没挂载会报错
# Executing grub-2.12-r5.trigger # Executing grub-2.12-r5.trigger
@ -1540,6 +1546,64 @@ EOF
show_nixos_config show_nixos_config
} }
basic_init() {
os_dir=$1
# 此时不能用
# chroot $os_dir timedatectl set-timezone Asia/Shanghai
# Failed to create bus connection: No such file or directory
# debian 11 没有 systemd-firstboot
if is_have_cmd_on_disk $os_dir systemd-firstboot; then
if chroot $os_dir systemd-firstboot --help | grep -wq '\--force'; then
chroot $os_dir systemd-firstboot --timezone=Asia/Shanghai --force
else
chroot $os_dir systemd-firstboot --timezone=Asia/Shanghai
fi
fi
# gentoo 不会自动创建 machine-id
clear_machine_id $os_dir
# sshd
chroot $os_dir ssh-keygen -A
sshd_enabled=false
sshs="sshd.service ssh.service sshd.socket ssh.socket"
for i in $sshs; do
if chroot $os_dir systemctl -q is-enabled $i; then
sshd_enabled=true
break
fi
done
if ! $sshd_enabled; then
for i in $sshs; do
if chroot $os_dir systemctl -q enable $i; then
break
fi
done
fi
allow_root_password_login $os_dir
allow_password_login $os_dir
if is_need_change_ssh_port; then
change_ssh_port $os_dir $ssh_port
fi
# 修改密码
change_root_password $os_dir
# 下载 fix-eth-name.service
# 即使开了 net.ifnames=0 也需要
# 因为 alpine 和目标系统的网卡顺序可能不同
# 无需执行 systemctl daemon-reload
# 因为 chroot 下执行会提示 Running in chroot, ignoring command 'daemon-reload'
download "$confhome/fix-eth-name.sh" "$os_dir/fix-eth-name.sh"
download "$confhome/fix-eth-name.service" "$os_dir/etc/systemd/system/fix-eth-name.service"
chroot "$os_dir" systemctl enable fix-eth-name
}
install_arch_gentoo() { install_arch_gentoo() {
info "install $distro" info "install $distro"
@ -1777,15 +1841,24 @@ EOF
# 第二次运行会报错 # 第二次运行会报错
useradd systemd-network || true useradd systemd-network || true
create_cloud_init_network_config net.cfg create_cloud_init_network_config net.cfg
cat -n net.cfg
# 正常应该是 -D gentoo但 alpine 的 cloud-init 包缺少 gentoo 配置 # 正常应该是 -D gentoo但 alpine 的 cloud-init 包缺少 gentoo 配置
cloud-init devel net-convert -p net.cfg -k yaml -d out -D alpine -O networkd cloud-init devel net-convert -p net.cfg -k yaml -d out -D alpine -O networkd
cp out/etc/systemd/network/10-cloud-init-eth*.network $os_dir/etc/systemd/network/ cp out/etc/systemd/network/10-cloud-init-eth*.network $os_dir/etc/systemd/network/
rm -rf out
# 删除 cloud-init
rm -rf net.cfg out
apk del cloud-init
# 删除网卡名匹配 # 删除网卡名匹配
sed -i '/^Name=/d' $os_dir/etc/systemd/network/10-cloud-init-eth*.network sed -i '/^Name=/d' $os_dir/etc/systemd/network/10-cloud-init-eth*.network
rm -rf net.cfg
apk del cloud-init # 下载 fix-eth-name.service
# chroot 下执行 systemctl daemon-reload
# 会提示 Running in chroot, ignoring command 'daemon-reload'
download "$confhome/fix-eth-name.sh" "$os_dir/fix-eth-name.sh"
download "$confhome/fix-eth-name.service" "$os_dir/etc/systemd/system/fix-eth-name.service"
chroot "$os_dir" systemctl enable fix-eth-name
# arch gentoo 网络配置是用 alpine cloud-init 生成的 # arch gentoo 网络配置是用 alpine cloud-init 生成的
# cloud-init 版本够新,因此无需修复 onlink 网关 # cloud-init 版本够新,因此无需修复 onlink 网关
@ -2270,6 +2343,10 @@ create_cloud_init_network_config() {
fi fi
apk del "$(get_yq_name)" apk del "$(get_yq_name)"
# 查看文件
info "Cloud-init network config"
cat -n $ci_file >&2
} }
# 实测没用,生成的 machine-id 是固定的 # 实测没用,生成的 machine-id 是固定的
@ -2470,6 +2547,11 @@ restore_resolv_conf() {
fi fi
} }
keep_now_resolv_conf() {
os_dir=$1
rm -f $os_dir/etc/resolv.conf.orig
}
# 抄 https://github.com/alpinelinux/alpine-conf/blob/3.18.1/setup-disk.in#L421 # 抄 https://github.com/alpinelinux/alpine-conf/blob/3.18.1/setup-disk.in#L421
get_alpine_firmware_pkgs() { get_alpine_firmware_pkgs() {
# 需要有 modloop不然 modinfo 会报错 # 需要有 modloop不然 modinfo 会报错
@ -2539,6 +2621,63 @@ get_ucode_firmware_pkgs() {
esac esac
} }
chroot_systemctl_disable() {
os_dir=$1
shift
for unit in "$@"; do
# 如果传进来的是x(没有.) 则改成 x.service
if ! [[ "$unit" = "*.*" ]]; then
unit=$i.service
fi
# debian 10 返回值始终是 0
if ! chroot $os_dir systemctl list-unit-files "$unit" 2>&1 | grep -Eq '^0 unit'; then
chroot $os_dir systemctl disable "$unit"
fi
done
}
disable_cloud_init() {
os_dir=$1
info "Disable Cloud-Init"
# 两种方法都可以
if [ -d $os_dir/etc/cloud ]; then
touch $os_dir/etc/cloud/cloud-init.disabled
fi
for name in cloud-init-local cloud-init cloud-config cloud-final; do
for type in service socket; do
# 服务不存在时会报错
chroot $os_dir systemctl disable "$name.$type" 2>/dev/null || true
done
done
}
create_network_manager_config() {
source_cfg=$1
os_dir=$2
info "Create Network-Manager config"
# 可以直接用 alpine 的 cloud-init 生成 Network Manager 配置
apk add cloud-init
cloud-init devel net-convert -p "$source_cfg" -k yaml -d /out -D alpine -O network-manager
sed -i -e '/^may-fail=/d' -e 's/^method=dhcp/method=auto/' \
/out/etc/NetworkManager/system-connections/cloud-init-eth*.nmconnection
cp /out/etc/NetworkManager/system-connections/cloud-init-eth*.nmconnection $os_dir/etc/NetworkManager/system-connections/
rm -rf /out
apk del cloud-init
# 最终显示文件
for file in "$os_dir"/etc/NetworkManager/system-connections/cloud-init-eth*.nmconnection; do
cat -n "$file" >&2
done
}
modify_linux() { modify_linux() {
os_dir=$1 os_dir=$1
info "Modify Linux" info "Modify Linux"
@ -2565,11 +2704,10 @@ EOF
done done
} }
download_cloud_init_config $os_dir # 部分镜像有默认配置,例如 centos
del_exist_sysconfig_NetworkManager_config $os_dir
clear_machine_id $os_dir # 仅 fedora (el/ol/国产fork 用的是复制文件方法)
# el/ol/fedora/国产fork
# 1. 禁用 selinux kdump # 1. 禁用 selinux kdump
# 2. 添加微码+固件 # 2. 添加微码+固件
if [ -f $os_dir/etc/redhat-release ]; then if [ -f $os_dir/etc/redhat-release ]; then
@ -2578,7 +2716,15 @@ EOF
mount_pseudo_fs $os_dir mount_pseudo_fs $os_dir
cp_resolv_conf $os_dir cp_resolv_conf $os_dir
disable_cloud_init $os_dir
# 可以直接用 alpine 的 cloud-init 生成 Network Manager 配置
create_cloud_init_network_config /net.cfg
create_network_manager_config /net.cfg "$os_dir"
rm /net.cfg
disable_selinux_kdump $os_dir disable_selinux_kdump $os_dir
if fw_pkgs=$(get_ucode_firmware_pkgs) && [ -n "$fw_pkgs" ]; then if fw_pkgs=$(get_ucode_firmware_pkgs) && [ -n "$fw_pkgs" ]; then
is_have_cmd_on_disk $os_dir dnf && mgr=dnf || mgr=yum is_have_cmd_on_disk $os_dir dnf && mgr=dnf || mgr=yum
chroot $os_dir $mgr install -y $fw_pkgs chroot $os_dir $mgr install -y $fw_pkgs
@ -2594,13 +2740,15 @@ EOF
# 注意 ubuntu 也有 /etc/debian_version # 注意 ubuntu 也有 /etc/debian_version
if [ "$distro" = debian ]; then if [ "$distro" = debian ]; then
# 修复 onlink 网关 # 修复 onlink 网关
add_onlink_script_if_need # add_onlink_script_if_need
mount_pseudo_fs $os_dir mount_pseudo_fs $os_dir
cp_resolv_conf $os_dir cp_resolv_conf $os_dir
find_and_mount /boot find_and_mount /boot
find_and_mount /boot/efi find_and_mount /boot/efi
disable_cloud_init $os_dir
# 获取当前开启的 Components, 后面要用 # 获取当前开启的 Components, 后面要用
if [ -f $os_dir/etc/apt/sources.list.d/debian.sources ]; then if [ -f $os_dir/etc/apt/sources.list.d/debian.sources ]; then
comps=$(grep ^Components: $os_dir/etc/apt/sources.list.d/debian.sources | head -1 | cut -d' ' -f2-) comps=$(grep ^Components: $os_dir/etc/apt/sources.list.d/debian.sources | head -1 | cut -d' ' -f2-)
@ -2674,32 +2822,73 @@ EOF
chroot_apt_install $os_dir $fw_pkgs chroot_apt_install $os_dir $fw_pkgs
fi fi
if [ "$releasever" -le 11 ]; then # genericcloud 删除以下文件开机时才会显示 grub 菜单
chroot $os_dir apt-get update # https://salsa.debian.org/cloud-team/debian-cloud-images/-/tree/master/config_space/bookworm/files/etc/default/grub.d
rm -f $os_dir/etc/default/grub.d/10_cloud.cfg
rm -f $os_dir/etc/default/grub.d/15_timeout.cfg
chroot $os_dir update-grub
if true; then if true; then
# 将 debian 11 设置为 12 一样的网络管理器 # 如果使用 nocloud 镜像
# 可解决 ifupdown dhcp 不支持 24位掩码+不规则网关的问题 chroot_apt_install $os_dir openssh-server
chroot_apt_install $os_dir netplan.io else
chroot $os_dir systemctl disable networking resolvconf # 如果使用 genericcloud 镜像
chroot $os_dir systemctl enable systemd-networkd systemd-resolved
rm_resolv_conf $os_dir # 还原默认配置并创建 key
ln -sf ../run/systemd/resolve/stub-resolv.conf $os_dir/etc/resolv.conf # cat $os_dir/usr/share/openssh/sshd_config $os_dir/etc/ssh/sshd_config
# chroot $os_dir ssh-keygen -A
rm -rf $os_dir/etc/ssh/sshd_config
UCF_FORCE_CONFFMISS=1 chroot $os_dir dpkg-reconfigure openssh-server
fi
# 镜像自带的网络管理器
# debian 11 ifupdown
# debian 12 netplan + networkd + resolved
# ifupdown dhcp 不支持 24位掩码+不规则网关?
# 强制使用 netplan
if false && is_have_cmd_on_disk $os_dir netplan; then
chroot_apt_install $os_dir netplan.io
# 服务不存在时会报错
chroot $os_dir systemctl disable networking resolvconf 2>/dev/null || true
chroot $os_dir systemctl enable systemd-networkd systemd-resolved
rm_resolv_conf $os_dir
ln -sf ../run/systemd/resolve/stub-resolv.conf $os_dir/etc/resolv.conf
if [ -f "$os_dir/etc/cloud/cloud.cfg.d/99_fallback.cfg" ]; then
insert_into_file $os_dir/etc/cloud/cloud.cfg.d/99_fallback.cfg after '#cloud-config' <<EOF insert_into_file $os_dir/etc/cloud/cloud.cfg.d/99_fallback.cfg after '#cloud-config' <<EOF
system_info: system_info:
network: network:
renderers: [netplan] renderers: [netplan]
activators: [netplan] activators: [netplan]
EOF EOF
else
# debian 11 默认不支持 rdnss要安装 rdnssd 或者 nm
chroot_apt_install $os_dir rdnssd
fi fi
fi fi
# 不会自动建立链接,因此不能删除 create_ifupdown_config $os_dir/etc/network/interfaces
restore_resolv_conf $os_dir
# ifupdown 不支持 rdnss
# 但 iso 安装不会安装 rdnssd而是在安装时读取 rdnss 并写入 resolv.conf
if false; then
chroot_apt_install $os_dir rdnssd
fi
# debian 10 11 云镜像安装了 resolvconf
# debian 12 云镜像安装了 netplan systemd-resolved
# 云镜像用了 cloud-init 自动配置网络,用户是无感的,因此官方云镜像可以随便选择网络管理器
# 但我们的系统安装后用户可能有手动配置网络的需求,因此用回 iso 安装时的网络管理器 ifupdown
# 服务不存在时会报错
chroot $os_dir systemctl disable resolvconf systemd-networkd systemd-resolved 2>/dev/null || true
chroot_apt_install $os_dir ifupdown
chroot_apt_remove $os_dir resolvconf netplan.io systemd-resolved
chroot_apt_autoremove $os_dir
chroot $os_dir systemctl enable networking
# 静态时 networking 服务不会根据 /etc/network/interfaces 更新 resolv.conf
# 动态时使用了 isc-dhcp-client 支持自动更新 resolv.conf
# 另外 debian iso 不会安装 rdnssd
keep_now_resolv_conf $os_dir
fi fi
# opensuse # opensuse
@ -2713,16 +2902,53 @@ EOF
find_and_mount /boot find_and_mount /boot
find_and_mount /boot/efi find_and_mount /boot/efi
disable_cloud_init $os_dir
# opensuse leap # opensuse leap
if grep opensuse-leap $os_dir/etc/os-release; then if grep opensuse-leap $os_dir/etc/os-release; then
# 修复 onlink 网关
add_onlink_script_if_need # sysconfig ifcfg
create_cloud_init_network_config $os_dir/net.cfg
chroot $os_dir cloud-init devel net-convert \
-p /net.cfg -k yaml -d out -D opensuse -O sysconfig
# sysconfig ifroute
# 包括了修复 onlink 网关
for ethx in $(get_eths); do
for prefix in '' 'default '; do
if is_staticv4; then
get_netconf_to ipv4_gateway
echo "${prefix}${ipv4_gateway} - -" >>$os_dir/out/etc/sysconfig/network/ifroute-$ethx
fi
if is_staticv6; then
get_netconf_to ipv6_gateway
echo "${prefix}${ipv6_gateway} - -" >>$os_dir/out/etc/sysconfig/network/ifroute-$ethx
fi
done
done
for file in \
"$os_dir/out/etc/sysconfig/network/ifcfg-eth"* \
"$os_dir/out/etc/sysconfig/network/ifroute-eth"*; do
# 动态 ip 没有 ifroute-eth*
if [ -f $file ]; then
cp $file $os_dir/etc/sysconfig/network/
fi
done
rm -rf $os_dir/net.cfg $os_dir/out
fi fi
# opensuse tumbleweed # opensuse tumbleweed
# 更新到 cloud-init 24.1 后删除 # network-manager
if grep opensuse-tumbleweed $os_dir/etc/os-release; then if grep opensuse-tumbleweed $os_dir/etc/os-release; then
touch $os_dir/etc/NetworkManager/NetworkManager.conf # 如果使用 cloud-init 则需要 touch NetworkManager.conf
# 更新到 cloud-init 24.1 后删除
# touch $os_dir/etc/NetworkManager/NetworkManager.conf
# 可以直接用 alpine 的 cloud-init 生成 Network Manager 配置
create_cloud_init_network_config /net.cfg
create_network_manager_config /net.cfg "$os_dir"
rm /net.cfg
fi fi
# 不能同时装 kernel-default-base 和 kernel-default # 不能同时装 kernel-default-base 和 kernel-default
@ -2810,10 +3036,10 @@ EOF
add_onlink_script_if_need add_onlink_script_if_need
fi fi
# 修复 cloud-init + sysconfig / NetworkManager 的各种网络问题 basic_init $os_dir
if [ -d "$os_dir/etc/sysconfig" ] || [ -d "$os_dir/etc/NetworkManager" ]; then
fix_sysconfig_NetworkManager $os_dir # 应该在这里是否运行了 basic_init 和创建了网络配置文件
fi # 如果没有,则使用 cloud-init
# 查看 cloud-init 最终配置 # 查看 cloud-init 最终配置
if [ -f "$ci_file" ]; then if [ -f "$ci_file" ]; then
@ -3226,9 +3452,8 @@ is_el7_family() {
! is_have_cmd_on_disk "$1" dnf ! is_have_cmd_on_disk "$1" dnf
} }
fix_sysconfig_NetworkManager() { del_exist_sysconfig_NetworkManager_config() {
os_dir=$1 os_dir=$1
ci_file=$os_dir/etc/cloud/cloud.cfg.d/99_fallback.cfg
# 删除云镜像自带的 dhcp 配置,防止歧义 # 删除云镜像自带的 dhcp 配置,防止歧义
rm -rf $os_dir/etc/NetworkManager/system-connections/*.nmconnection rm -rf $os_dir/etc/NetworkManager/system-connections/*.nmconnection
@ -3238,14 +3463,17 @@ fix_sysconfig_NetworkManager() {
# 甲骨文 dhcpv6 获取不到 IP 将视为 fatal原有的 ipv4 地址也会被删除 # 甲骨文 dhcpv6 获取不到 IP 将视为 fatal原有的 ipv4 地址也会被删除
# 2. 修复 dhcpv6 下ifcfg 添加了 IPV6_AUTOCONF=no 导致无法获取网关 # 2. 修复 dhcpv6 下ifcfg 添加了 IPV6_AUTOCONF=no 导致无法获取网关
# 3. 修复 dhcpv6 下NM method=dhcp 导致无法获取网关 # 3. 修复 dhcpv6 下NM method=dhcp 导致无法获取网关
if false; then
ci_file=$os_dir/etc/cloud/cloud.cfg.d/99_fallback.cfg
insert_into_file $ci_file after '^runcmd:' <<EOF insert_into_file $ci_file after '^runcmd:' <<EOF
- sed -i '/^IPV[46]_FAILURE_FATAL=/d' /etc/sysconfig/network-scripts/ifcfg-* || true - sed -i '/^IPV[46]_FAILURE_FATAL=/d' /etc/sysconfig/network-scripts/ifcfg-* || true
- sed -i '/^may-fail=/d' /etc/NetworkManager/system-connections/*.nmconnection || true - sed -i '/^may-fail=/d' /etc/NetworkManager/system-connections/*.nmconnection || true
- for f in /etc/sysconfig/network-scripts/ifcfg-*; do grep -q '^DHCPV6C=yes' "\$f" && sed -i '/^IPV6_AUTOCONF=no/d' "\$f"; done - for f in /etc/sysconfig/network-scripts/ifcfg-*; do grep -q '^DHCPV6C=yes' "\$f" && sed -i '/^IPV6_AUTOCONF=no/d' "\$f"; done
- sed -i 's/^method=dhcp/method=auto/' /etc/NetworkManager/system-connections/*.nmconnection || true - sed -i 's/^method=dhcp/method=auto/' /etc/NetworkManager/system-connections/*.nmconnection || true
- systemctl is-enabled NetworkManager && systemctl restart NetworkManager || true - systemctl is-enabled NetworkManager && systemctl restart NetworkManager || true
EOF EOF
fi
} }
install_qcow_by_copy() { install_qcow_by_copy() {
@ -3258,6 +3486,14 @@ install_qcow_by_copy() {
esac esac
) )
# yum/apt 安装软件时需要的内存总大小
need_ram=$(
case "$distro" in
ubuntu) echo 1024 ;;
*) echo 2048 ;;
esac
)
connect_qcow connect_qcow
# 镜像分区格式 # 镜像分区格式
@ -3371,40 +3607,65 @@ install_qcow_by_copy() {
umount /nbd-efi/ umount /nbd-efi/
fi fi
# 断开 qcow # 断开 qcow 并删除 qemu-img
info "Disconnecting qcow2"
if is_have_cmd vgchange; then if is_have_cmd vgchange; then
vgchange -an vgchange -an
apk del lvm2
fi fi
disconnect_qcow disconnect_qcow
# 已复制并断开连接 qcow可删除 qemu-img
apk del qemu-img apk del qemu-img
# 取消挂载硬盘
info "Unmounting disk"
if is_efi; then
umount /os/boot/efi/
fi
umount /os/
umount /installer/
# 如果镜像有efi分区复制其uuid # 如果镜像有efi分区复制其uuid
# 如果有相同uuid的fat分区则无法挂载 # 如果有相同uuid的fat分区则无法挂载
# 所以要先复制efi分区断开nbd再复制uuid # 所以要先复制efi分区断开nbd再复制uuid
# 复制uuid前要取消挂载硬盘 efi 分区
if is_efi && [ -n "$efi_part_uuid" ]; then if is_efi && [ -n "$efi_part_uuid" ]; then
umount /os/boot/efi/ info "Copy efi partition uuid"
apk add mtools apk add mtools
mlabel -N "$(echo $efi_part_uuid | sed 's/-//')" -i /dev/$xda*1 ::$efi_part_label mlabel -N "$(echo $efi_part_uuid | sed 's/-//')" -i /dev/$xda*1 ::$efi_part_label
apk del mtools
update_part update_part
fi
# 删除 installer 分区并扩容
info "Delete installer partition"
apk add parted
parted /dev/$xda -s -- rm 3
update_part
resize_after_install_cloud_image
# 重新挂载 /os /boot/efi
info "Re-mount disk"
mount -o noatime /dev/$xda*2 /os/
if is_efi; then
mount -o $efi_mount_opts /dev/$xda*1 /os/boot/efi/ mount -o $efi_mount_opts /dev/$xda*1 /os/boot/efi/
fi fi
# 创建 swap
create_swap_if_ram_less_than $need_ram /os/swapfile
# 挂载伪文件系统 # 挂载伪文件系统
mount_pseudo_fs /os/ mount_pseudo_fs /os/
# 创建 swap
umount /installer/
mkswap /dev/$xda*3
swapon /dev/$xda*3
modify_el_ol() { modify_el_ol() {
info "Modify el ol" info "Modify el ol"
os_dir=/os
# resolv.conf # resolv.conf
cp_resolv_conf /os cp_resolv_conf /os
# 部分镜像有默认配置,例如 centos
del_exist_sysconfig_NetworkManager_config /os
# 删除镜像的默认账户,防止使用默认账户密码登录 ssh # 删除镜像的默认账户,防止使用默认账户密码登录 ssh
del_default_user /os del_default_user /os
@ -3445,9 +3706,6 @@ install_qcow_by_copy() {
chroot_dnf install $fw_pkgs chroot_dnf install $fw_pkgs
fi fi
# 修复 cloud-init + dhcp 的各种网络问题
fix_sysconfig_NetworkManager /os
# fstab 删除多余分区 # fstab 删除多余分区
# almalinux/rocky 镜像有 boot 分区 # almalinux/rocky 镜像有 boot 分区
# oracle 镜像有 swap 分区 # oracle 镜像有 swap 分区
@ -3554,6 +3812,81 @@ EOF
# --update-bls-cmdline # --update-bls-cmdline
chroot /os/ grub2-mkconfig -o "$grub_o_cfg" chroot /os/ grub2-mkconfig -o "$grub_o_cfg"
# 网络配置
# el7/8 sysconfig
# el9 network-manager
if [ -f $os_dir/etc/sysconfig/network-scripts/ifup-eth ]; then
# sysconfig
info 'sysconfig'
# anolis/openeuler/opencloudos 可能要安装 cloud-init
# opencloudos 无法使用 chroot $os_dir command -v xxx
# chroot: failed to run command command: No such file or directory
# 注意还要禁用 cloud-init 服务
if ! is_have_cmd_on_disk $os_dir cloud-init; then
chroot_dnf install cloud-init
fi
# cloud-init 路径
# /usr/lib/python2.7/site-packages/cloudinit/net/
# /usr/lib/python3/dist-packages/cloudinit/net/
# /usr/lib/python3.9/site-packages/cloudinit/net/
# el7 不认识 static6但可改成 static作用相同
recognize_static6=true
if ls $os_dir/usr/lib/python*/*-packages/cloudinit/net/sysconfig.py 2>/dev/null &&
! grep -q static6 $os_dir/usr/lib/python*/*-packages/cloudinit/net/sysconfig.py; then
recognize_static6=false
fi
# cloud-init 20.1 才支持以下配置
# https://cloudinit.readthedocs.io/en/20.4/topics/network-config-format-v1.html#subnet-ip
# https://cloudinit.readthedocs.io/en/21.1/topics/network-config-format-v1.html#subnet-ip
# ipv6_dhcpv6-stateful: Configure this interface with dhcp6
# ipv6_dhcpv6-stateless: Configure this interface with SLAAC and DHCP
# ipv6_slaac: Configure address with SLAAC
# el7 最新 cloud-init 版本
# centos 7 19.4-7.0.5.el7_9.6 backport 了 ipv6_xxx
# openeuler 20.03 19.4-15.oe2003sp4 backport 了 ipv6_xxx
# anolis 7 19.1.17-1.0.1.an7 没有更新到 centos7 相同版本,也没 backport ipv6_xxx
# 最好还修改 ifcfg-eth* 的 IPV6_AUTOCONF
# 但实测 anolis7 cloud-init dhcp6 不会生成 IPV6_AUTOCONF因此暂时不管
# https://www.redhat.com/zh/blog/configuring-ipv6-rhel-7-8
recognize_ipv6_types=true
if ls -d $os_dir/usr/lib/python*/*-packages/cloudinit/net/ 2>/dev/null &&
! grep -qr ipv6_slaac $os_dir/usr/lib/python*/*-packages/cloudinit/net/; then
recognize_ipv6_types=false
fi
# 生成 cloud-init 网络配置
create_cloud_init_network_config $os_dir/net.cfg "$recognize_static6" "$recognize_ipv6_types"
# 转换成目标系统的网络配置
chroot $os_dir cloud-init devel net-convert \
-p /net.cfg -k yaml -d out -D rhel -O sysconfig
cp $os_dir/out/etc/sysconfig/network-scripts/ifcfg-eth* $os_dir/etc/sysconfig/network-scripts/
rm -rf $os_dir/net.cfg $os_dir/out
# 修正网络配置问题并显示文件
sed -i '/^IPV[46]_FAILURE_FATAL=/d' $os_dir/etc/sysconfig/network-scripts/ifcfg-*
for file in "$os_dir/etc/sysconfig/network-scripts/ifcfg-"*; do
if grep -q '^DHCPV6C=yes' "$file"; then
sed -i '/^IPV6_AUTOCONF=no/d' "$file"
fi
cat -n "$file"
done
else
# Network Manager
info 'Network Manager'
create_cloud_init_network_config /net.cfg
create_network_manager_config /net.cfg "$os_dir"
rm /net.cfg
fi
# 不删除可能网络管理器不会写入dns # 不删除可能网络管理器不会写入dns
rm_resolv_conf /os rm_resolv_conf /os
} }
@ -3622,11 +3955,44 @@ EOF
chroot_apt_install $os_dir $fw_pkgs chroot_apt_install $os_dir $fw_pkgs
fi fi
# 16.04 镜像用 ifupdown/networking 管理网络 # 网络配置
# 要安装 resolveconf不然 /etc/resolv.conf 为空 # 18.04+ netplan
if [ "$releasever" = 16.04 ]; then if is_have_cmd_on_disk $os_dir netplan; then
# 生成 cloud-init 网络配置
create_cloud_init_network_config $os_dir/net.cfg
# ubuntu 18.04 cloud-init 版本 23.1.2,因此不用处理 onlink
# 如果不是输出到 / 则不会生成 50-cloud-init.yaml
# 注意比较多了什么东西
if false; then
chroot $os_dir cloud-init devel net-convert \
-p /net.cfg -k yaml -d /out -D ubuntu -O netplan
sed -Ei "/^[[:space:]]+set-name:/d" $os_dir/out/etc/netplan/50-cloud-init.yaml
cp $os_dir/out/etc/netplan/50-cloud-init.yaml $os_dir/etc/netplan/
rm -rf $os_dir/net.cfg $os_dir/out
else
chroot $os_dir cloud-init devel net-convert \
-p /net.cfg -k yaml -d / -D ubuntu -O netplan
sed -Ei "/^[[:space:]]+set-name:/d" $os_dir/etc/netplan/50-cloud-init.yaml
rm -rf $os_dir/net.cfg
fi
else
# 16.04 镜像用 ifupdown/networking 管理网络
# 要安装 resolveconf不然 /etc/resolv.conf 为空
chroot_apt_install $os_dir resolvconf chroot_apt_install $os_dir resolvconf
ln -sf /run/resolvconf/resolv.conf $os_dir/etc/resolv.conf.orig ln -sf /run/resolvconf/resolv.conf $os_dir/etc/resolv.conf.orig
create_ifupdown_config $os_dir/etc/network/interfaces
fi
# 自带的 60-cloudimg-settings.conf 禁止了 PasswordAuthentication
file=$os_dir/etc/ssh/sshd_config.d/60-cloudimg-settings.conf
if [ -f $file ]; then
sed -i '/^PasswordAuthentication/d' $file
if [ -z "$(cat $file)" ]; then
rm -f $file
fi
fi fi
# 安装 bios 引导 # 安装 bios 引导
@ -3679,64 +4045,18 @@ EOF
restore_resolv_conf $os_dir restore_resolv_conf $os_dir
} }
# anolis/openeuler/opencloudos 可能要安装 cloud-init
# opencloudos 无法使用 chroot $os_dir command -v xxx
# chroot: failed to run command command: No such file or directory
if is_have_cmd_on_disk $os_dir rpm &&
! is_have_cmd_on_disk $os_dir cloud-init; then
cp_resolv_conf $os_dir
chroot_dnf install cloud-init
restore_resolv_conf $os_dir
fi
# cloud-init 路径
# /usr/lib/python2.7/site-packages/cloudinit/net/
# /usr/lib/python3/dist-packages/cloudinit/net/
# /usr/lib/python3.9/site-packages/cloudinit/net/
# el7 不认识 static6但可改成 static作用相同
recognize_static6=true
if ls $os_dir/usr/lib/python*/*-packages/cloudinit/net/sysconfig.py 2>/dev/null &&
! grep -q static6 $os_dir/usr/lib/python*/*-packages/cloudinit/net/sysconfig.py; then
recognize_static6=false
fi
# cloud-init 20.1 才支持以下配置
# https://cloudinit.readthedocs.io/en/20.4/topics/network-config-format-v1.html#subnet-ip
# https://cloudinit.readthedocs.io/en/21.1/topics/network-config-format-v1.html#subnet-ip
# ipv6_dhcpv6-stateful: Configure this interface with dhcp6
# ipv6_dhcpv6-stateless: Configure this interface with SLAAC and DHCP
# ipv6_slaac: Configure address with SLAAC
# el7 最新 cloud-init 版本
# centos 7 19.4-7.0.5.el7_9.6 backport 了 ipv6_xxx
# openeuler 20.03 19.4-15.oe2003sp4 backport 了 ipv6_xxx
# anolis 7 19.1.17-1.0.1.an7 没有更新到 centos7 相同版本,也没 backport ipv6_xxx
# 最好还修改 ifcfg-eth* 的 IPV6_AUTOCONF
# 但实测 anolis7 cloud-init dhcp6 不会生成 IPV6_AUTOCONF因此暂时不管
# https://www.redhat.com/zh/blog/configuring-ipv6-rhel-7-8
recognize_ipv6_types=true
if ls -d $os_dir/usr/lib/python*/*-packages/cloudinit/net/ 2>/dev/null &&
! grep -qr ipv6_slaac $os_dir/usr/lib/python*/*-packages/cloudinit/net/; then
recognize_ipv6_types=false
fi
# cloud-init
download_cloud_init_config "$os_dir" "$recognize_static6" "$recognize_ipv6_types"
case "$distro" in case "$distro" in
ubuntu) modify_ubuntu ;; ubuntu) modify_ubuntu ;;
*) modify_el_ol ;; *) modify_el_ol ;;
esac esac
# 查看最终的 cloud-init 配置 # 基本配置
cat /os/etc/cloud/cloud.cfg.d/99_*.cfg disable_cloud_init /os
basic_init /os
# 删除installer分区重启后cloud init会自动扩容 # 删除 swapfile
swapoff -a swapoff -a
parted /dev/$xda -s rm 3 rm -f /os/swapfile
} }
get_partition_table_format() { get_partition_table_format() {