Skip to content

Commit

Permalink
ubuntu: iso 安装适配 --minimal
Browse files Browse the repository at this point in the history
  • Loading branch information
bin456789 committed Sep 6, 2024
1 parent 32d3bc8 commit 5388dd7
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 56 deletions.
1 change: 1 addition & 0 deletions reinstall.sh
Original file line number Diff line number Diff line change
Expand Up @@ -975,6 +975,7 @@ setos() {

# ks
eval ${step}_ks=$confhome/ubuntu.yaml
eval ${step}_minimal=$minimal
fi
}

Expand Down
132 changes: 78 additions & 54 deletions trans.sh
Original file line number Diff line number Diff line change
Expand Up @@ -1638,9 +1638,13 @@ EOF
rm -rf $os_dir/swapfile
}

get_http_file_size_to() {
var_name=$1
url=$2
get_http_file_size() {
url=$1

# 网址重定向可能得到多个 Content-Length, 选最后一个
wget --spider -S "$url" 2>&1 | grep 'Content-Length:' |
tail -1 | awk '{print $2}' | grep .
}

pipe_extract() {
# alpine busybox 自带 gzip,但官方版也许性能更好
Expand Down Expand Up @@ -1717,10 +1721,8 @@ create_part() {
# xda*1 星号用于 nvme0n1p1 的字母 p
# shellcheck disable=SC2154
if [ "$distro" = windows ]; then
get_http_file_size_to size_bytes $iso

# 默认值,最大的iso 23h2 需要7g
if [ -z "$size_bytes" ]; then
if ! size_bytes=$(get_http_file_size "$iso"); then
# 默认值,最大的iso 23h2 假设 7g
size_bytes=$((7 * 1024 * 1024 * 1024))
fi

Expand Down Expand Up @@ -1762,7 +1764,7 @@ create_part() {
mkfs.ntfs -f -F -L installer /dev/$xda*2 #2 installer
fi
elif is_use_cloud_image; then
installer_part_size="$(get_ci_installer_part_size)"
installer_part_size="$(get_cloud_image_part_size)"
# 这几个系统不使用dd,而是复制文件
if [ "$distro" = centos ] || [ "$distro" = alma ] || [ "$distro" = rocky ] ||
[ "$distro" = oracle ] || [ "$distro" = redhat ] ||
Expand Down Expand Up @@ -1844,8 +1846,24 @@ create_part() {
# 对于红帽系是临时分区表,安装时除了 installer 分区,其他分区会重建为默认的大小
# 对于ubuntu是最终分区表,因为 ubuntu 的安装器不能调整个别分区,只能重建整个分区表
# installer 2g分区用fat格式刚好塞得下ubuntu-22.04.3 iso,而ext4塞不下或者需要改参数
[ "$distro" = ubuntu ] && installer_part_size=3GiB || installer_part_size=2GiB
if [ "$distro" = ubuntu ]; then
if ! size_bytes=$(get_http_file_size "$iso"); then
# 默认值,假设 iso 3g
size_bytes=$((3 * 1024 * 1024 * 1024))
fi
# 假设需要预留 10% 空间
size_bytes_mb=$((size_bytes * 110 / 100 / 1024 / 1024))
installer_part_size=${size_bytes_mb}MiB
else
# redhat
installer_part_size=2GiB
fi

# centos 7 无法加载alpine格式化的ext4
# 要关闭这个属性
ext4_options="-O ^metadata_csum"
apk add dosfstools

if is_efi; then
# efi
parted /dev/$xda -s -- \
Expand All @@ -1856,9 +1874,9 @@ create_part() {
set 1 boot on
update_part

mkfs.fat -n efi /dev/$xda*1 #1 efi
mkfs.ext4 -E nodiscard -F -L os /dev/$xda*2 #2 os
mkfs.fat -n installer /dev/$xda*3 #3 installer
mkfs.fat -n efi /dev/$xda*1 #1 efi
mkfs.ext4 -E nodiscard -F -L os /dev/$xda*2 #2 os
mkfs.ext4 -E nodiscard -F -L installer $ext4_options /dev/$xda*3 #2 installer
elif is_xda_gt_2t; then
# bios > 2t
parted /dev/$xda -s -- \
Expand All @@ -1869,9 +1887,9 @@ create_part() {
set 1 bios_grub on
update_part

echo #1 bios_boot
mkfs.ext4 -E nodiscard -F -L os /dev/$xda*2 #2 os
mkfs.fat -n installer /dev/$xda*3 #3 installer
echo #1 bios_boot
mkfs.ext4 -E nodiscard -F -L os /dev/$xda*2 #2 os
mkfs.ext4 -E nodiscard -F -L installer $ext4_options /dev/$xda*3 #3 installer
else
# bios
parted /dev/$xda -s -- \
Expand All @@ -1881,18 +1899,10 @@ create_part() {
set 1 boot on
update_part

mkfs.ext4 -E nodiscard -F -L os /dev/$xda*1 #1 os
mkfs.fat -n installer /dev/$xda*2 #2 installer
mkfs.ext4 -E nodiscard -F -L os /dev/$xda*1 #1 os
mkfs.ext4 -E nodiscard -F -L installer $ext4_options /dev/$xda*2 #2 installer
fi
update_part

# centos 7 无法加载alpine格式化的ext4
# 要关闭这个属性
# 目前改用fat格式,不用设置这个
if false && [ "$distro" = centos ]; then
apk add e2fsprogs-extra
tune2fs -O ^metadata_csum_seed /dev/disk/by-label/installer
fi
fi

update_part
Expand Down Expand Up @@ -2560,7 +2570,7 @@ get_os_fs() {
esac
}

get_ci_installer_part_size() {
get_cloud_image_part_size() {
# 8
# https://repo.almalinux.org/almalinux/8/cloud/x86_64/images/AlmaLinux-8-GenericCloud-latest.x86_64.qcow2 600m
# https://download.rockylinux.org/pub/rocky/8/images/x86_64/Rocky-8-GenericCloud-Base.latest.x86_64.qcow2 1.8g
Expand Down Expand Up @@ -2592,7 +2602,7 @@ get_ci_installer_part_size() {
else
echo 2GiB
fi
elif get_http_file_size_to size_bytes $img >&2 && [ -n "$size_bytes" ]; then
elif size_bytes=$(get_http_file_size "$img"); then
# 额外 +100M 文件系统保留大小 和 qcow2 写入空间
size_bytes_mb=$((size_bytes / 1024 / 1024 + 100))
# 最少 1g ,因为可能要用作临时 swap
Expand Down Expand Up @@ -3929,38 +3939,31 @@ get_ubuntu_kernel_flavor() {
# 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

# TODO: ISO virtual-hwe-24.04 不安装 linux-image-extra-virtual-hwe-24.04 不然会花屏

# 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
{
# busybox blkid 不显示 sr0 的 UUID
if [ "$releasever" = 16.04 ]; then
if is_virt; then
flavor=virtual-hwe-$releasever
else
flavor=generic-hwe-$releasever
fi
if [ "$releasever" = 16.04 ]; then
if is_virt; then
echo virtual-hwe-$releasever
else
apk add lsblk

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 lsblk -o UUID,LABEL | grep -i 9796-932E | grep -i config-2; then
flavor=ibm
elif is_virt; then
flavor=virtual-hwe-$releasever
echo generic-hwe-$releasever
fi
else
vendor="$(get_cloud_vendor)"
case "$vendor" in
aws | gcp | oracle | azure | ibm) echo $vendor ;;
*)
if is_virt; then
echo virtual-hwe-$releasever
else
flavor=generic-hwe-$releasever
echo generic-hwe-$releasever
fi
fi
} >&2
echo $flavor
;;
esac
fi
}

install_redhat_ubuntu() {
Expand Down Expand Up @@ -3996,9 +3999,30 @@ install_redhat_ubuntu() {
# shellcheck disable=SC2154
if [ "$distro" = "ubuntu" ]; then
download $iso /os/installer/ubuntu.iso
mkdir -p /iso
mount -o ro /os/installer/ubuntu.iso /iso

# 内核风味
kernel=$(get_ubuntu_kernel_flavor)

# 要安装的版本
# https://canonical-subiquity.readthedocs-hosted.com/en/latest/reference/autoinstall-reference.html#id
# 20.04 不能选择 minimal ,也没有 install-sources.yaml
source_id=
if [ -f /iso/casper/install-sources.yaml ]; then
ids=$(grep id: /iso/casper/install-sources.yaml | awk '{print $2}')
if [ "$(echo "$ids" | wc -l)" = 1 ]; then
source_id=$ids
else
[ "$minimal" = 1 ] && v= || v=-v
source_id=$(echo "$ids" | grep $v '\-minimal')

if [ "$(echo "$source_id" | wc -l)" -gt 1 ]; then
error_and_exit "find multi source id."
fi
fi
fi

# 正常写法应该是 ds="nocloud-net;s=https://xxx/" 但是甲骨文云的ds更优先,自己的ds根本无访问记录
# $seed 是 https://xxx/
cat <<EOF >$grub_cfg
Expand All @@ -4009,7 +4033,7 @@ install_redhat_ubuntu() {
insmod all_video
search --no-floppy --label --set=root installer
loopback loop /ubuntu.iso
linux (loop)/casper/vmlinuz iso-scan/filename=/ubuntu.iso autoinstall noprompt noeject cloud-config-url=$ks $extra_cmdline extra_kernel=$kernel --- $console_cmdline
linux (loop)/casper/vmlinuz iso-scan/filename=/ubuntu.iso autoinstall noprompt noeject cloud-config-url=$ks $extra_cmdline extra_kernel=$kernel extra_source_id=$source_id --- $console_cmdline
initrd (loop)/casper/initrd
}
EOF
Expand Down
19 changes: 17 additions & 2 deletions ubuntu.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ autoinstall:
apt:
fallback: offline-install
source:
id: ubuntu-server-minimal
search_drivers: false
id: "@SOURCE_ID@"
kernel:
package: linux-generic
timezone: Asia/Shanghai
Expand All @@ -31,11 +30,27 @@ autoinstall:
export xda
curl -L "$confhome/ubuntu-storage-early.sh" | sh -s
# 要安装的版本
# 有的镜像只有一个版本,没有 install-sources.yaml
# 因此提取不到 $source_id,此时 $source_id 参数为空
if [ -n "$source_id" ]; then
sed -i "s/@SOURCE_ID@/$source_id/" /autoinstall.yaml
else
sed -i "/@SOURCE_ID@/d" /autoinstall.yaml
fi
# 内核风味
# https://bugs.launchpad.net/subiquity/+bug/1989353
sed -i "s/generic/$kernel/" /run/kernel-meta-package
sed -i "/package:/s/generic/$kernel/" /autoinstall.yaml
# 跳过最后的更新
cp /usr/sbin/chroot /usr/sbin/chroot.bin
cat >/usr/sbin/chroot <<EOF
#!/bin/sh
[ "\$2" = "unattended-upgrades" ] || /usr/sbin/chroot.bin "\$@"
EOF
# 禁用 DNS 强制离线安装内核和跳过最后的更新
# 但安装器会配置时区和写入最近的mirror到/etc/apt/sources.list 所以要提前解析
# dig会显示cname结果,cname会以.结尾,grep -v '\.$' 表示去除 cname 结果
Expand Down

0 comments on commit 5388dd7

Please sign in to comment.