ubuntu: 改用复制文件安装

This commit is contained in:
bin456789 2024-04-27 09:45:10 +08:00
parent 6ac1feb025
commit 3aa0084bea
No known key found for this signature in database
GPG Key ID: EE301B386DE6C11B
4 changed files with 299 additions and 140 deletions

View File

@ -64,6 +64,7 @@ All features can be used on both Linux and Windows.
### Feature 1: Install Linux
- If no version number is entered, the latest version will be installed.
- When installing on a virtual machine, it will automatically select a slimmed-down kernel.
```bash
bash reinstall.sh centos 7|8|9 (8|9 for the stream version)

View File

@ -64,6 +64,7 @@ certutil -urlcache -f -split https://mirror.ghproxy.com/https://raw.githubuserco
### 功能 1: 安装 Linux
- 不输入版本号,则安装最新版
- 在虚拟机上,会自动安装精简内核
```bash
bash reinstall.sh centos 7|8|9 (8|9 为 stream 版本)

View File

@ -786,15 +786,12 @@ setos() {
else
ci_mirror=https://cloud-images.ubuntu.com
fi
eval ${step}_img=$ci_mirror/releases/$releasever/release/ubuntu-$releasever-server-cloudimg-$basearch_alt.img
# minimal 镜像内核风味是 kvm后台 vnc 无显示
# 没有 aarch64 minimal 镜像
# TODO: 在 trans 里安装普通内核/云内核
use_minimal_image=false
if $use_minimal_image && [ "$basearch" = x86_64 ]; then
# 20.04/22.04 minimal 镜像没有 aarch64
if { { [ "$releasever" = 20.04 ] || [ "$releasever" = 22.04 ]; } && [ "$basearch_alt" = amd64 ]; } ||
[ "$releasever" = 24.04 ]; then
eval ${step}_img=$ci_mirror/minimal/releases/$codename/release/ubuntu-$releasever-minimal-cloudimg-$basearch_alt.img
else
eval ${step}_img=$ci_mirror/releases/$releasever/release/ubuntu-$releasever-server-cloudimg-$basearch_alt.img
fi
else
# 传统安装
@ -1022,6 +1019,8 @@ setos() {
}
eval ${step}_distro=$distro
eval ${step}_releasever=$releasever
if is_distro_like_redhat $distro; then
setos_redhat
else

254
trans.sh
View File

@ -1305,14 +1305,17 @@ create_part() {
mkfs.ntfs -f -F -L installer /dev/$xda*2 #2 installer
fi
elif is_use_cloud_image; then
# 这几个系统不使用dd而是复制文件因为dd这几个系统的qcow2需要10g硬盘
if { [ "$distro" = centos ] || [ "$distro" = alma ] || [ "$distro" = rocky ]; }; then
installer_part_size="$(get_ci_installer_part_size)"
# 这几个系统不使用dd而是复制文件
if [ "$distro" = centos ] || [ "$distro" = alma ] || [ "$distro" = rocky ] ||
[ "$distro" = ubuntu ]; then
fs="$(get_os_fs)"
if is_efi; then
parted /dev/$xda -s -- \
mklabel gpt \
mkpart '" "' fat32 1MiB 601MiB \
mkpart '" "' xfs 601MiB -2GiB \
mkpart '" "' ext4 -2GiB 100% \
mkpart '" "' fat32 1MiB 101MiB \
mkpart '" "' $fs 101MiB -$installer_part_size \
mkpart '" "' ext4 -$installer_part_size 100% \
set 1 esp on
update_part /dev/$xda
@ -1323,8 +1326,8 @@ create_part() {
parted /dev/$xda -s -- \
mklabel gpt \
mkpart '" "' ext4 1MiB 2MiB \
mkpart '" "' xfs 2MiB -2GiB \
mkpart '" "' ext4 -2GiB 100% \
mkpart '" "' $fs 2MiB -$installer_part_size \
mkpart '" "' ext4 -$installer_part_size 100% \
set 1 bios_grub on
update_part /dev/$xda
@ -1333,8 +1336,8 @@ create_part() {
mkfs.ext4 -F -L installer /dev/$xda*3 #3 installer
fi
else
# fedora debian ubuntu opensuse arch gentoo
installer_part_size=1GiB
# 使用 dd qcow2
# fedora debian opensuse arch gentoo
parted /dev/$xda -s -- \
mklabel gpt \
mkpart '" "' ext4 1MiB -$installer_part_size \
@ -1718,6 +1721,7 @@ EOF
fi
# debian 网络问题
# 注意 ubuntu 也有 /etc/debian_version
if [ -f $os_dir/etc/debian_version ]; then
# 修复 onlink 网关
add_onlink_script_if_need
@ -1731,7 +1735,8 @@ EOF
if true; then
# 将 debian 10/11 设置为 12 一样的网络管理器
# 可解决 ifupdown dhcp 不支持 24位掩码+不规则网关的问题
chroot $os_dir apt install -y netplan.io
chroot $os_dir apt update
DEBIAN_FRONTEND=noninteractive chroot $os_dir apt install -y netplan.io
chroot $os_dir systemctl disable networking resolvconf
chroot $os_dir systemctl enable systemd-networkd systemd-resolved
rm -f $os_dir/etc/resolv.conf $os_dir/etc/resolv.conf.orig
@ -1745,7 +1750,8 @@ EOF
else
# debian 10/11 默认不支持 rdnss要安装 rdnssd 或者 nm
chroot $os_dir apt install -y rdnssd
chroot $os_dir apt update
DEBIAN_FRONTEND=noninteractive chroot $os_dir apt install -y rdnssd
# 不会自动建立链接,因此不能删除
mv $os_dir/etc/resolv.conf.orig $os_dir/etc/resolv.conf
fi
@ -1968,7 +1974,21 @@ disconnect_qcow() {
fi
}
install_qcow_el() {
get_os_fs() {
case "$distro" in
ubuntu) echo ext4 ;;
centos | alma | rocky) echo xfs ;;
esac
}
get_ci_installer_part_size() {
case "$distro" in
centos | alma | rocky) echo 2GiB ;;
*) echo 1GiB ;;
esac
}
install_qcow_by_copy() {
yum() {
if [ "$releasever" = 7 ]; then
chroot /os/ yum -y --disablerepo=* --enablerepo=base,updates "$@"
@ -1977,12 +1997,35 @@ install_qcow_el() {
fi
}
mount_nouuid() {
case "$fs" in
ext4) mount "$@" ;;
xfs) mount -o nouuid "$@" ;;
esac
}
efi_label=$(
case "$distro" in
ubuntu) echo UEFI ;;
*) echo ;;
esac
)
efi_mount_opts=$(
case "$distro" in
ubuntu) echo "umask=0077" ;;
*) echo "defaults,uid=0,gid=0,umask=077,shortname=winnt" ;;
esac
)
fs="$(get_os_fs)"
connect_qcow
# TODO: 改成循环mount找出os+fstab查找剩余分区
os_part=$(lsblk /dev/nbd0p*[0-9] --sort SIZE -no NAME,FSTYPE | grep xfs | tail -1 | cut -d' ' -f1)
os_part=$(lsblk /dev/nbd0p*[0-9] --sort SIZE -no NAME,FSTYPE | grep $fs | tail -1 | cut -d' ' -f1)
efi_part=$(lsblk /dev/nbd0p*[0-9] --sort SIZE -no NAME,FSTYPE | grep fat | tail -1 | cut -d' ' -f1)
boot_part=$(lsblk /dev/nbd0p*[0-9] --sort SIZE -no NAME,FSTYPE | grep xfs | sed '$d' | tail -1 | cut -d' ' -f1)
boot_part=$(lsblk /dev/nbd0p*[0-9] --sort SIZE -no NAME,FSTYPE | grep $fs | sed '$d' | tail -1 | cut -d' ' -f1)
os_part_uuid=$(lsblk /dev/$os_part -no UUID)
if [ -n "$efi_part" ]; then
@ -1993,26 +2036,30 @@ install_qcow_el() {
# 使用目标系统的格式化程序
# centos8 如果用alpine格式化xfsgrub2-mkconfig和grub2里面都无法识别xfs分区
mount -o nouuid /dev/$os_part /nbd/
mount_nouuid /dev/$os_part /nbd/
mount_pseudo_fs /nbd/
chroot /nbd mkfs.xfs -f -m uuid=$os_part_uuid /dev/$xda*2
case "$distro" in
ubuntu) chroot /nbd mkfs.ext4 -F -L cloudimg-rootfs -U $os_part_uuid /dev/$xda*2 ;;
*) chroot /nbd mkfs.xfs -f -m uuid=$os_part_uuid /dev/$xda*2 ;;
esac
umount -R /nbd/
# TODO: ubuntu 镜像缺少 mkfs.fat/vfat/dosfstools? initrd 不需要检查fs完整性
# 复制系统
echo Copying os partition
mount -o ro,nouuid /dev/$os_part /nbd/
echo Copying os partition...
mount_nouuid -o ro /dev/$os_part /nbd/
mount -o noatime /dev/$xda*2 /os/
cp -a /nbd/* /os/
# 复制boot分区如果有
if [ -n "$boot_part" ]; then
echo Copying boot partition
mount -o ro,nouuid /dev/$boot_part /nbd-boot/
echo Copying boot partition...
mount_nouuid -o ro /dev/$boot_part /nbd-boot/
cp -a /nbd-boot/* /os/boot/
fi
# efi 分区
efi_mount_opts="defaults,uid=0,gid=0,umask=077,shortname=winnt"
if is_efi; then
# 挂载 efi
mkdir -p /os/boot/efi/
@ -2020,7 +2067,7 @@ install_qcow_el() {
# 复制文件
if [ -n "$efi_part" ]; then
echo Copying efi partition
echo Copying efi partition...
mount -o ro /dev/$efi_part /nbd-efi/
cp -a /nbd-efi/* /os/boot/efi/
fi
@ -2036,7 +2083,7 @@ install_qcow_el() {
if is_efi && [ -n "$efi_part_uuid" ]; then
umount /os/boot/efi/
apk add mtools
mlabel -N "$(echo $efi_part_uuid | sed 's/-//')" -i /dev/$xda*1
mlabel -N "$(echo $efi_part_uuid | sed 's/-//')" -i /dev/$xda*1 ::$efi_label
update_part /dev/$xda
mount -o $efi_mount_opts /dev/$xda*1 /os/boot/efi/
fi
@ -2045,18 +2092,20 @@ install_qcow_el() {
mount_pseudo_fs /os/
# 创建 swap
rm -rf /installer/*
create_swap 1024 /installer/swapfile
umount /installer/
mkswap /dev/$xda*3
swapon /dev/$xda*3
# cloud-init
download_cloud_init_config /os
modify_el() {
# resolv.conf
cp /etc/resolv.conf /os/etc/resolv.conf
# selinux kdump
disable_selinux_kdump /os
# cloud-init
download_cloud_init_config /os
# 部分镜像例如 centos7 要手动删除 machine-id
truncate_machine_id /os
@ -2154,10 +2203,102 @@ EOF
# 不删除可能网络管理器不会写入dns
rm -f /os/etc/resolv.conf
}
modify_ubuntu() {
os_dir=/os
mv $os_dir/etc/resolv.conf $os_dir/etc/resolv.conf.orig
cp /etc/resolv.conf $os_dir/etc/resolv.conf
# 关闭 os prober因为 os prober 有时很慢
cp $os_dir/etc/default/grub $os_dir/etc/default/grub.orig
echo 'GRUB_DISABLE_OS_PROBER=true' >>$os_dir/etc/default/grub
# 更改源
if is_in_china; then
sed -i 's/archive.ubuntu.com/cn.archive.ubuntu.com/' $os_dir/etc/apt/sources.list
fi
# 安装最佳内核
flavor=$(get_ubuntu_kernel_flavor)
echo "Use kernel flavor: $flavor"
chroot $os_dir apt update
DEBIAN_FRONTEND=noninteractive chroot $os_dir apt install -y "linux-image-$flavor"
# 自带内核:
# 常规版本 generic
# minimal 20.04/22.04 kvm # 后台 vnc 无显示
# minimal 24.04 virtual
# 标记旧内核包
# 注意排除 linux-base
pkgs=$(chroot $os_dir apt-mark showmanual linux-* | grep -E 'generic|virtual|kvm' | grep -v $flavor)
chroot $os_dir apt-mark auto $pkgs
# 使用 autoremove
conf=$os_dir/etc/apt/apt.conf.d/01autoremove
sed -i.orig 's/VersionedKernelPackages/x/; s/NeverAutoRemove/x/' $conf
DEBIAN_FRONTEND=noninteractive chroot $os_dir apt autoremove --purge -y
mv $conf.orig $conf
# 安装 bios 引导
if ! is_efi; then
chroot $os_dir grub-install /dev/$xda
fi
# 更改 efi 目录的 grub.cfg 写死的 fsuuid
# 因为 24.04 fsuuid 对应 boot 分区
efi_grub_cfg=$os_dir/boot/efi/EFI/ubuntu/grub.cfg
if is_efi; then
os_uuid=$(lsblk -rno UUID /dev/$xda*2)
sed -Ei "s|[0-9a-f-]{36}|$os_uuid|i" $efi_grub_cfg
# 24.04 移除 boot 分区后,需要添加 /boot 路径
if grep "'/grub'" $efi_grub_cfg; then
sed -i "s|'/grub'|'/boot/grub'|" $efi_grub_cfg
fi
fi
# 处理 40-force-partuuid.cfg
force_partuuid_cfg=$os_dir/etc/default/grub.d/40-force-partuuid.cfg
if [ -e $force_partuuid_cfg ]; then
if is_virt; then
# 更改写死的 partuuid
os_part_uuid=$(lsblk -rno PARTUUID /dev/$xda*2)
sed -i "s/^GRUB_FORCE_PARTUUID=.*/GRUB_FORCE_PARTUUID=$os_part_uuid/" $force_partuuid_cfg
else
# 独服不应该使用 initrdless boot
sed -i "/^GRUB_FORCE_PARTUUID=/d" $force_partuuid_cfg
fi
fi
# 要重新生成 grub.cfg因为
# 1 我们删除了 boot 分区
# 2 改动了 /etc/default/grub.d/40-force-partuuid.cfg
chroot $os_dir update-grub
# 还原 grub 配置os prober
mv $os_dir/etc/default/grub.orig $os_dir/etc/default/grub
# fstab
# 24.04 镜像有boot分区但我们不需要
sed -i '/[[:space:]]\/boot[[:space:]]/d' $os_dir/etc/fstab
if ! is_efi; then
# bios 删除 efi 条目
sed -i '/[[:space:]]\/boot\/efi[[:space:]]/d' $os_dir/etc/fstab
fi
mv $os_dir/etc/resolv.conf.orig $os_dir/etc/resolv.conf
}
case "$distro" in
ubuntu) modify_ubuntu ;;
*) modify_el ;;
esac
# 删除installer分区重启后cloud init会自动扩容
swapoff -a
umount /installer
parted /dev/$xda -s rm 3
}
@ -2782,11 +2923,11 @@ install_windows() {
# Windows cannot access the required file Drive:\Sources\Boot.wim.
# Make sure all files required for installation are available and restart the installation.
# Error code: 0x80070491
ls -lh /iso/sources/boot.wim
ls -lh /os/boot.wim
du -h /iso/sources/boot.wim
du -h /os/boot.wim
# wimdelete /os/boot.wim 1
wimoptimize /os/boot.wim
ls -lh /os/boot.wim
du -h /os/boot.wim
# 将 boot.wim 放到正确的位置
if is_efi; then
@ -2853,6 +2994,32 @@ refind_main_disk() {
fi
}
get_ubuntu_kernel_flavor() {
# 20.04/22.04 kvm 内核 vnc 没显示
# 24.04 kvm = virtual
# linux-image-virtual = linux-image-6.x-generic
# linux-image-generic = linux-image-6.x-generic + amd64-microcode + intel-microcode + linux-firmware + linux-modules-extra-generic
# https://github.com/systemd/systemd/blob/main/src/basic/virt.c
# https://github.com/canonical/cloud-init/blob/main/tools/ds-identify
# http://git.annexia.org/?p=virt-what.git;a=blob;f=virt-what.in;hb=HEAD
{
if is_dmi_contains "amazon" || is_dmi_contains "ec2"; then
flavor=aws
elif is_dmi_contains "Google Compute Engine" || is_dmi_contains "GoogleCloud"; then
flavor=gcp
elif is_dmi_contains "OracleCloud"; then
flavor=oracle
elif is_dmi_contains "7783-7084-3265-9085-8269-3286-77"; then
flavor=azure
elif is_virt; then
flavor=virtual-hwe-$releasever
else
flavor=generic-hwe-$releasever
fi
} >&2
echo $flavor
}
install_redhat_ubuntu() {
# 安装 grub2
if is_efi; then
@ -2887,20 +3054,7 @@ install_redhat_ubuntu() {
if [ "$distro" = "ubuntu" ]; then
download $iso /os/installer/ubuntu.iso
# https://github.com/systemd/systemd/blob/main/src/basic/virt.c
# https://github.com/canonical/cloud-init/blob/main/tools/ds-identify
# http://git.annexia.org/?p=virt-what.git;a=blob;f=virt-what.in;hb=HEAD
if is_dmi_contains "amazon" || is_dmi_contains "ec2"; then
kernel=aws
elif is_dmi_contains "Google Compute Engine" || is_dmi_contains "GoogleCloud"; then
kernel=gcp
elif is_dmi_contains "OracleCloud"; then
kernel=oracle
elif is_dmi_contains "7783-7084-3265-9085-8269-3286-77"; then
kernel=azure
else
kernel=generic
fi
kernel=$(get_ubuntu_kernel_flavor)
# 正常写法应该是 ds="nocloud-net;s=https://xxx/" 但是甲骨文云的ds更优先自己的ds根本无访问记录
# $seed 是 https://xxx/
@ -2990,10 +3144,14 @@ if is_use_cloud_image; then
case "$distro" in
centos | alma | rocky)
# 这几个系统云镜像系统盘是8~9g xfs而我们的目标是能在5g硬盘上运行因此改成复制系统文件
install_qcow_el
install_qcow_by_copy
;;
ubuntu)
# 24.04 云镜像有 boot 分区(在系统分区之前),因此不直接 dd 云镜像
install_qcow_by_copy
;;
*)
# debian ubuntu fedora opensuse arch gentoo any
# debian fedora opensuse arch gentoo any
dd_qcow
resize_after_install_cloud_image
modify_os_on_disk linux