From 72f486d2526d39bd3815af56c077a854c9980c3b Mon Sep 17 00:00:00 2001 From: bin456789 Date: Sat, 13 May 2023 00:14:46 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=B9=E7=94=A8=20alpine=20=E4=BD=9C?= =?UTF-8?q?=E4=B8=BA=E4=B8=AD=E9=97=B4=E7=B3=BB=E7=BB=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- ks.cfg | 92 +++++++----- reinstall.sh | 321 +++++++++++++++++++++++++--------------- resize.sh | 7 +- trans.sh | 176 +++++++++++++++------- ubuntu-storage-early.sh | 18 +-- user-data | 12 +- 7 files changed, 406 insertions(+), 222 deletions(-) diff --git a/README.md b/README.md index 5ee996b..9720543 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Usage: ``` curl -O https://raw.githubusercontent.com/bin456789/reinstall/main/reinstall.sh -bash reinstall.sh centos-7/8/9 alma-8/9 rocky-8/9 fedora-36/37/38 ubuntu-20.04/22.04 +bash reinstall.sh centos-7/8/9 alma-8/9 rocky-8/9 fedora-36/37/38 ubuntu-20.04/22.04 alpine-3.16/3.17/3.18 reboot ``` Username: `root` diff --git a/ks.cfg b/ks.cfg index 14a8f01..030e252 100644 --- a/ks.cfg +++ b/ks.cfg @@ -1,4 +1,4 @@ -# shellcheck disable=2148,2215 +# shellcheck disable=2148 # 设置 keyboard --vckeymap=us --xlayouts='us' lang en_US.UTF-8 @@ -18,38 +18,9 @@ part / --fstype=ext4 --grow # 不用 xfs 因为不能缩小容量 # 软件 %packages --ignoremissing # el9 minimal.iso fedora Server repo/iso 没有 tuned @^Minimal Install -tuned +tuned # 改善性能 %include /tmp/include-packages-for-resize - -# 不删除usb相关的包,因为甲骨文云有usb设备,作用未知 -# -usb_modeswitch -# -usbutils - -# 无线 --iw --crda --rfkill -# shellcheck disable=2211 --iwl*-firmware - -# 虚拟机用不上 --irqbalance # 多核+直通设备可能有用? --microcode_ctl --smartmontools --aic94xx-firmware --alsa-firmware --ivtv-firmware -# -linux-firmware # 去除后安装centos 8会报错 - -# fedora --amd-gpu-firmware --atheros-firmware --brcmfmac-firmware --intel-gpu-firmware --mt7xxx-firmware --nvidia-gpu-firmware --realtek-firmware - +%include /tmp/exclude-packages-for-vm %end # 禁用防火墙 @@ -67,6 +38,13 @@ selinux --disabled distro=$(awk -F: '{ print $3 }' $include + # 不删除usb相关的包 因为甲骨文云有usb设备 作用未知 + # -usb_modeswitch + # -usbutils + + # 无线 + -iw + -crda + -rfkill + -iwl*-firmware + + # 其他 + -irqbalance # 多核+直通设备可能有用? + -microcode_ctl + -smartmontools + + # 各种固件 + -aic94xx-firmware + -alsa-firmware + -ivtv-firmware + # -linux-firmware # 去除后安装centos 8会报错 + + # fedora 特有固件 + -amd-gpu-firmware + -atheros-firmware + -brcmfmac-firmware + -intel-gpu-firmware + -mt7xxx-firmware + -nvidia-gpu-firmware + -realtek-firmware +EOF +fi # 设置安装源 include=/tmp/include-url-command @@ -128,8 +137,11 @@ fi # 分步安装的系统,要将最后一个分区(installer)合并到系统分区 if [ -e /dev/disk/by-label/installer ]; then - # 提取 extra.confhome - eval "$(grep -o '\bextra\.[^ ]*' /proc/cmdline | sed 's/\bextra.//')" + # 提取 extra.localtest extra.confhome extra.mirrorlist + prefix=extra + for var in $(grep -o "\b$prefix\.[^ ]*" /proc/cmdline | xargs); do + eval "$(echo $var | sed -E "s/$prefix\.([^=]*)=(.*)/\1='\2'/")" + done cd / curl -O $confhome/resize.sh diff --git a/reinstall.sh b/reinstall.sh index 6a19d10..2746927 100644 --- a/reinstall.sh +++ b/reinstall.sh @@ -3,21 +3,47 @@ confhome=https://raw.githubusercontent.com/bin456789/reinstall/main localtest_confhome=http://192.168.253.1 usage_and_exit() { - echo "Usage: reinstall.sh centos-7/8/9 alma-8/9 rocky-8/9 fedora-36/37/38 ubuntu-20.04/22.04" + echo "Usage: reinstall.sh centos-7/8/9 alma-8/9 rocky-8/9 fedora-36/37/38 ubuntu-20.04/22.04 alpine-3.16/3.17/3.18" exit 1 } is_in_china() { - # https://geoip.ubuntu.com/lookup - curl -L https://geoip.fedoraproject.org/city | grep -w CN + if [ -z $_is_in_china ]; then + # https://geoip.ubuntu.com/lookup + curl -L https://geoip.fedoraproject.org/city | grep -w CHN + _is_in_china=$? + fi + return $_is_in_china } setos() { - step=$1 - distro=$2 - releasever=$3 - ks=$4 - vault=$5 + local step=$1 + local distro=$2 + local releasever=$3 + local ks=$4 + + setos_alpine() { + eval ${step}_distro=$distro + + if [ "$localtest" = 1 ]; then + mirror=$confhome/alpine-netboot-3.17.3-x86_64/boot + eval ${step}_vmlinuz=$mirror/vmlinuz-lts + eval ${step}_initrd=$mirror/initramfs-lts + eval ${step}_repo=https://mirrors.aliyun.com/alpine/v3.17/main + eval ${step}_modloop=$mirror/modloop-lts + else + # 不要用https 因为甲骨文云arm initramfs阶段不会从硬件同步时钟,导致访问https出错 + if is_in_china; then + mirror=http://mirrors.aliyun.com/alpine/v$releasever + else + mirror=http://dl-cdn.alpinelinux.org/alpine/v$releasever + fi + eval ${step}_vmlinuz=$mirror/releases/$basearch/netboot/vmlinuz-lts + eval ${step}_initrd=$mirror/releases/$basearch/netboot/initramfs-lts + eval ${step}_repo=$mirror/main + eval ${step}_modloop=$mirror/releases/$basearch/netboot/modloop-lts + fi + } setos_ubuntu() { if [ "$localtest" = 1 ]; then @@ -48,40 +74,28 @@ setos() { eval ${step}_distro=ubuntu } - setos_rh() { + setos_redhat() { if [ "$localtest" = 1 ]; then mirror=$confhome/$releasever/ eval ${step}_ks=$confhome/$ks else - # 甲骨文 arm 1g内存,用 centos 7.9 镜像会 oom 进不了安装界面,所以用7.6 - if [ "$vault" = 1 ]; then - if is_in_china; then - [ "$basearch" = "x86_64" ] && dir= || dir=/altarch - mirror="https://mirrors.aliyun.com/centos-vault$dir/7.6.1810/os/$basearch/" - else - [ "$basearch" = "x86_64" ] && dir=centos || dir=altarch - mirror=http://vault.centos.org/$dir/7.6.1810/os/$basearch/ - fi - else - case $distro in - "centos") - case $releasever in - "7") mirrorlist="http://mirrorlist.centos.org/?release=7&arch=$basearch&repo=os" ;; - "8") mirrorlist="http://mirrorlist.centos.org/?release=8-stream&arch=$basearch&repo=BaseOS" ;; - "9") mirrorlist="https://mirrors.centos.org/mirrorlist?repo=centos-baseos-9-stream&arch=$basearch" ;; - esac - ;; - "alma") mirrorlist="https://mirrors.almalinux.org/mirrorlist/$releasever/baseos" ;; - "rocky") mirrorlist="https://mirrors.rockylinux.org/mirrorlist?arch=$basearch&repo=BaseOS-$releasever" ;; - "fedora") mirrorlist="https://mirrors.fedoraproject.org/mirrorlist?arch=$basearch&repo=fedora-$releasever" ;; + case $distro in + "centos") + case $releasever in + "7") mirrorlist="http://mirrorlist.centos.org/?release=7&arch=$basearch&repo=os" ;; + "8") mirrorlist="http://mirrorlist.centos.org/?release=8-stream&arch=$basearch&repo=BaseOS" ;; + "9") mirrorlist="https://mirrors.centos.org/mirrorlist?repo=centos-baseos-9-stream&arch=$basearch" ;; esac - # rocky/centos9 需要删除第一行注释, alma 需要替换$basearch,anigil 这个源不稳定 - mirror=$(curl -L $mirrorlist | sed "/^#/d" | sed "/anigil/d" | head -1 | sed "s,\$basearch,$basearch,") - eval "${step}_mirrorlist='${mirrorlist}'" - fi - eval ${step}_ks=$confhome/$ks + ;; + "alma") mirrorlist="https://mirrors.almalinux.org/mirrorlist/$releasever/baseos" ;; + "rocky") mirrorlist="https://mirrors.rockylinux.org/mirrorlist?arch=$basearch&repo=BaseOS-$releasever" ;; + "fedora") mirrorlist="https://mirrors.fedoraproject.org/mirrorlist?arch=$basearch&repo=fedora-$releasever" ;; + esac + # rocky/centos9 需要删除第一行注释, alma 需要替换$basearch,anigil 这个源不稳定 + mirror=$(curl -L $mirrorlist | sed "/^#/d" | sed "/anigil/d" | head -1 | sed "s,\$basearch,$basearch,") + eval "${step}_mirrorlist='${mirrorlist}'" fi - + eval ${step}_ks=$confhome/$ks eval ${step}_distro=${distro} eval ${step}_vmlinuz=${mirror}images/pxeboot/vmlinuz eval ${step}_initrd=${mirror}images/pxeboot/initrd.img @@ -92,20 +106,59 @@ setos() { fi } - if [ "$distro" = "ubuntu" ]; then - setos_ubuntu - else - setos_rh - fi + case "$distro" in + ubuntu) setos_ubuntu ;; + alpine) setos_alpine ;; + *) setos_redhat ;; + esac } +# 检查是否为正确的系统名 +verify_os_string() { + for os in 'centos-7|8|9' 'alma|rocky-8|9' 'fedora-36|37|38' 'ubuntu-20.04|22.04' 'alpine-3.16|3.17|3.18'; do + ds=$(echo $os | cut -d- -f1) + vers=$(echo $os | cut -d- -f2 | sed 's \. \\\. g') + finalos=$(echo "$@" | tr '[:upper:]' '[:lower:]' | sed -n -E "s,^($ds)[ :-]?($vers)$,\1:\2,p") + if [ -n "$finalos" ]; then + distro=$(echo $finalos | cut -d: -f1) + releasever=$(echo $finalos | cut -d: -f2) + return + fi + done + + echo "Please specify a proper os." + usage_and_exit +} + +apt_install() { + [ -z "$apk_updated" ] && apt update && apk_updated=1 + apt install -y $pkgs +} + +install_pkg() { + pkgs=$* + for pkg in $pkgs; do + if ! command -v $pkg; then + { + apt_install $pkgs || + dnf install -y $pkgs || + yum install -y $pkgs || + zypper install -y $pkgs || + pacman -Syu $pkgs || + apk add $pkgs + } 2>/dev/null + break + fi + done +} + +# 脚本入口 if [ "$EUID" -ne 0 ]; then echo "Please run as root." exit 1 fi -opts=$(getopt -a -n $0 --options l --long localtest -- "$@") -if [ "$?" != 0 ]; then +if ! opts=$(getopt -a -n $0 --options l --long localtest -- "$@"); then usage_and_exit fi @@ -128,68 +181,45 @@ while true; do esac done -# 检查是否为正确的系统名 -for re in \ - "s,.*\b(centos|alma|rocky)(linux)?[ :-]?([789])\b.*,\1:\3,p" \ - "s,.*\b(fedora)(linux)?[ :-]?(3[678])\b.*,\1:\3,p" \ - "s,.*\b(ubuntu)(linux)?[ :-]?(2[02]\.04)\b.*,\1:\3,p"; do - - finalos=$(echo "$@" | tr '[:upper:]' '[:lower:]' | sed -n -E "$re") - if [ -n "$finalos" ]; then - break - fi -done -if [ -z "$finalos" ]; then - echo "Please specify a proper os." - usage_and_exit -fi - -# 最小安装的 debian 不包含 curl dmidecode -install_pkg() { - pkgs=$1 - for pkg in $pkgs; do - if ! command -v $pkg; then - { - { apt update && apt install -y $pkgs; } || - dnf install -y $pkgs || - yum install -y $pkgs || - zypper install -y $pkgs || - pacman -Syu $pkgs - } 2>/dev/null - break - fi - done -} - -# 获取内存大小,lsmem最准确但centos7 arm不能用 -# arm 24g dmidecode 显示少了128m -ram_size=$(lsmem -b | grep 'Total online memory:' | awk '{ print $NF/1024/1024 }') -if [ -z $ram_size ]; then - install_pkg dmidecode - ram_size=$(dmidecode -t 17 | grep "Size.*[GM]B" | awk '{if ($3=="GB") s+=$2*1024; else s+=$2} END {print s}') -fi - -if [ $ram_size -lt 1024 ]; then - echo 'RAM < 1G. Unsupported.' - exit 1 -fi +verify_os_string "$@" +# 必备组件 install_pkg curl -distro=$(echo $finalos | cut -d: -f1) -releasever=$(echo $finalos | cut -d: -f2) -basearch=$(uname -m) +# alpine 自带的 grep 是 busybox 里面的, 要下载完整版grep +if [ -f /etc/alpine-release ]; then + apk add grep +fi -# 以下目标系统需要两步安装 -# ubuntu +# 获取内存大小,lsmem最准确但centos7 arm 和alpine不能用 +# arm 24g dmidecode 显示少了128m +if [ $distro != "alpine" ]; then + install_pkg util-linux + ram_size=$(lsmem -b 2>/dev/null | grep 'Total online memory:' | awk '{ print $NF/1024/1024 }') + if [ -z $ram_size ]; then + install_pkg dmidecode + ram_size=$(dmidecode -t 17 | grep "Size.*[GM]B" | awk '{if ($3=="GB") s+=$2*1024; else s+=$2} END {print s}') + fi + + if [ $ram_size -lt 1024 ]; then + echo 'RAM < 1G. Unsupported.' + exit 1 + fi +fi + +basearch=$(uname -m) +# 以下目标系统需要进入alpine环境安装 +# ubuntu/alpine # el8/9/fedora 任何架构 <2g # el7 aarch64 <1.5g -# shellcheck disable=SC2154 if [ $distro = "ubuntu" ] || + [ $distro = "alpine" ] || { [ $releasever -ge 8 ] && [ $ram_size -lt 2048 ]; } || { [ $releasever -eq 7 ] && [ $ram_size -lt 1536 ] && [ $basearch = "aarch64" ]; }; then [ $distro = "ubuntu" ] && ks=user-data || ks=ks.cfg + # 安装alpine时,使用指定的版本。 alpine作为中间系统时,使用 3.18 + [ $distro = "alpine" ] && alpine_releasever=$releasever || alpine_releasever=3.18 setos finalos $distro $releasever $ks - setos nextos centos 7 ks-trans.cfg 1 + setos nextos alpine $alpine_releasever else setos nextos $distro $releasever ks.cfg fi @@ -198,53 +228,110 @@ fi # shellcheck disable=SC2154 { cd / - curl -LO $nextos_vmlinuz - curl -LO $nextos_initrd + echo $nextos_vmlinuz + curl -Lo vmlinuz $nextos_vmlinuz + + echo $nextos_initrd + curl -Lo initrd $nextos_initrd touch reinstall.mark } # 转换 finalos_a=1 为 finalos.a=1 ,排除 finalos_mirrorlist build_finalos_cmdline() { - for var in $(compgen -v finalos_); do - key=${var//_/.} - [ $key != "finalos.mirrorlist" ] && finalos_cmdline+=" $key=${!var}" + for key in $(compgen -v finalos_); do + value=${!key} + key=${key#finalos_} + if [ -n "$value" ] && [ $key != "mirrorlist" ]; then + finalos_cmdline+=" finalos.$key=$value" + fi done } build_extra_cmdline() { - extra_cmdline+=" extra.confhome=$confhome" - if [ "$localtest" = 1 ]; then - extra_cmdline+=" extra.localtest=$localtest" - else - # 指定最终安装系统的 mirrorlist,链接有&,在grub中是特殊字符,所以要加引号 - if [ -n "$finalos_mirrorlist" ]; then - extra_cmdline+=" extra.mirrorlist='$finalos_mirrorlist'" - elif [ -n "$nextos_mirrorlist" ]; then - extra_cmdline+=" extra.mirrorlist='$nextos_mirrorlist'" + for key in localtest confhome; do + value=${!key} + if [ -n "$value" ]; then + extra_cmdline+=" extra.$key=$value" fi + done + + # 指定最终安装系统的 mirrorlist,链接有&,在grub中是特殊字符,所以要加引号 + if [ -n "$finalos_mirrorlist" ]; then + extra_cmdline+=" extra.mirrorlist='$finalos_mirrorlist'" + elif [ -n "$nextos_mirrorlist" ]; then + extra_cmdline+=" extra.mirrorlist='$nextos_mirrorlist'" fi } -# arm64 不需要添加 efi 字样 -if [ -d /sys/firmware/efi ] && [ "$basearch" = x86_64 ]; then - action='efi' -fi - build_finalos_cmdline build_extra_cmdline grub_cfg=$(find /boot -type f -name grub.cfg -exec grep -E -l 'menuentry|blscfg' {} \;) grub_cfg_dir=$(dirname $grub_cfg) +# 在x86 efi机器上,可能用 linux 或 linuxefi 加载内核 +# 通过检测原有的条目有没有 linuxefi 字样就知道当前 grub 用哪一种 +search_files=$(find /boot -type f -name grub.cfg) +if [ -d /boot/loader/entries/ ]; then + search_files="$search_files /boot/loader/entries/" +fi +if grep -q -r -E '^[[:blank:]]*linuxefi[[:blank:]]' $search_files; then + efi=efi +fi + +# 修改 alpine 启动时运行我们的脚本 +# shellcheck disable=SC2154,SC2164 +if [ -n "$finalos_cmdline" ]; then + install_pkg gzip cpio + + # 解压 + # 先删除临时文件,避免之前运行中断有残留文件 + tmp_dir=/tmp/reinstall/ + rm -rf $tmp_dir + mkdir -p $tmp_dir + cd $tmp_dir + zcat /initrd | cpio -idm + + # hack + # exec /bin/busybox switch_root $switch_root_opts $sysroot $chart_init "$KOPT_init" $KOPT_init_args # 3.17 + # exec switch_root $switch_root_opts $sysroot $chart_init "$KOPT_init" $KOPT_init_args # 3.18 + line_num=$(grep -E -n '^exec (/bin/busybox )?switch_root' init | cut -d: -f1) + line_num=$((line_num - 1)) + cat </initrd + + # 删除临时文件 + cd / + rm -rf $tmp_dir + + # 可添加 pkgs=xxx,yyy 启动时自动安装 + # apkovl=http://xxx.com/apkovl.tar.gz 可用,arm https未测但应该不行 + # apkovl=sda2:ext4:/apkovl.tar.gz 官方有写但不生效 + cmdline="alpine_repo=$nextos_repo modloop=$nextos_modloop $extra_cmdline $finalos_cmdline " +else + cmdline="root=live:$nextos_squashfs inst.ks=$nextos_ks $extra_cmdline" +fi + custom_cfg=$grub_cfg_dir/custom.cfg echo $custom_cfg -# shellcheck disable=SC2154 cat </sys/block/${1#/dev/}/device/rescan +} 2>/dev/null # el 自带 fdisk parted (el7的part不支持在线扩容) # ubuntu 自带 fdisk growpart @@ -52,6 +54,7 @@ case $part_fstype in xfs) xfs_growfs / ;; ext*) resize2fs /dev/$xda$part_num ;; esac +update_part /dev/$xda # 删除脚本自身 rm -f /resize.sh /etc/cron.d/resize diff --git a/trans.sh b/trans.sh index c734b20..d06cd9c 100644 --- a/trans.sh +++ b/trans.sh @@ -1,18 +1,94 @@ -# shellcheck disable=SC2148 -rescue --nomount -%pre +#!/bin/ash +# shellcheck shell=dash +# alpine 默认使用 busybox ash -exec >/dev/pts/0 2>&1 +# 显示输出到前台 +# 似乎script更优雅,但 alpine 不带 script 命令 +# script -f/dev/tty0 +exec >/dev/tty0 2>&1 + +# 提取 finalos/extra 到变量 +for prefix in finalos extra; do + for var in $(grep -o "\b$prefix\.[^ ]*" /proc/cmdline | xargs); do + eval "$(echo $var | sed -E "s/$prefix\.([^=]*)=(.*)/\1='\2'/")" + done +done + +# 找到主硬盘 +# alpine 不自带lsblk,liveos安装的软件也会被带到新系统,所以不用lsblk +# xda=$(lsblk -dn -o NAME | grep -E 'nvme0n1|.da') +# shellcheck disable=SC2010 +xda=$(ls /dev/ | grep -Ex '[shv]da|nvme0n1') + +# arm要手动从硬件同步时间,避免访问https出错 +hwclock -s + +# 安装并打开 ssh +echo root:123@@@ | chpasswd +printf '\nyes' | setup-sshd + +# shellcheck disable=SC2154 +if [ "$distro" = "alpine" ]; then + # 还原改动,不然本脚本会被复制到新系统 + rm -f /etc/local.d/trans.start + rm -f /etc/runlevels/default/local + + # 网络 + setup-interfaces -a # 生成 /etc/network/interfaces + rc-update add networking boot + + # 设置 + setup-keymap us us + setup-timezone -i Asia/Shanghai + setup-ntp chrony + + # 在 arm netboot initramfs init 中 + # 如果识别到rtc硬件,就往系统添加hwclock服务,否则添加swclock + # 这个设置也被复制到安装的系统中 + # 但是从initramfs chroot到真正的系统后,是能识别rtc硬件的 + # 所以我们手动改用hwclock修复这个问题 + rc-update del swclock boot + rc-update add hwclock boot + + # 通过 setup-alpine 安装会多启用几个服务 + # https://github.com/alpinelinux/alpine-conf/blob/c5131e9a038b09881d3d44fb35e86851e406c756/setup-alpine.in#L189 + # acpid | default + # crond | default + # seedrng | boot + + # 添加 virt-what 用到的社区仓库 + alpine_ver=$(cut -d. -f1,2 >/etc/apk/repositories + + # 如果是 vm 就用 virt 内核 + cp /etc/apk/world /tmp/world.old + apk add virt-what + if [ -n "$(virt-what)" ]; then + kernel_opt="-k virt" + fi + # 删除 virt-what 和依赖,不然会带到新系统 + apk del "$(diff /tmp/world.old /etc/apk/world | grep '^+' | sed '1d' | sed 's/^+//')" + + # 重置为官方仓库配置 + true >/etc/apk/repositories + setup-apkrepos -1 + setup-apkcache /var/cache/apk + + # 安装到硬盘 + # alpine默认使用 syslinux (efi 环境除外),这里强制使用 grub,方便用脚本再次重装 + export BOOTLOADER="grub" + printf 'y' | setup-disk -m sys $kernel_opt -s 0 /dev/$xda + exec reboot +fi download() { - # axel 有问题 - # axel "https://rocky-linux-us-south1.production.gcp.mirrors.ctrliq.cloud/pub/rocky//8.7/BaseOS/aarch64/os/images/pxeboot/vmlinuz" - # Initializing download: https://rocky-linux-us-south1.production.gcp.mirrors.ctrliq.cloud/pub/rocky//8.7/BaseOS/aarch64/os/images/pxeboot/vmlinuz - # Connection gone. + # 显示 url + echo $1 - # axel https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/archive-virtio/virtio-win-0.1.229-1/virtio-win-0.1.229.iso - # Initializing download: https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/archive-virtio/virtio-win-0.1.229-1/virtio-win-0.1.229.iso - # Too many redirects. + # 阿里云禁止 axel 下载 + # axel https://mirrors.aliyun.com/alpine/latest-stable/releases/x86_64/alpine-netboot-3.17.0-x86_64.tar.gz + # Initializing download: https://mirrors.aliyun.com/alpine/latest-stable/releases/x86_64/alpine-netboot-3.17.0-x86_64.tar.gz + # HTTP/1.1 403 Forbidden # 先用 axel 下载 [ -z $2 ] && save="" || save="-o $2" @@ -24,16 +100,25 @@ download() { } update_part() { - partprobe + hdparm -z $1 + partprobe $1 partx -u $1 udevadm settle -} + echo 1 >/sys/block/${1#/dev/}/device/rescan +} 2>/dev/null -# 找到主硬盘 -xda=$(lsblk -dn -o NAME | grep -E 'nvme0n1|.da') +if ! apk add util-linux axel grub udev hdparm e2fsprogs curl parted; then + echo 'Unable to install package!' + sleep 1m + exec reboot +fi + +# 打开dev才能刷新分区名 +rc-service udev start # 反激活 lvm -vgchange -an +# alpine live 不需要 +false && vgchange -an # 移除 lsblk 显示的分区 partx -d /dev/$xda @@ -46,6 +131,7 @@ disk_2t=$((2 * 1024 * 1024 * 1024 * 1024)) # {xda}*1 星号用于 nvme0n1p1 的字母 p if [ -d /sys/firmware/efi ]; then # efi + apk add dosfstools parted /dev/$xda -s -- \ mklabel gpt \ mkpart '" "' fat32 1MiB 1025MiB \ @@ -93,45 +179,36 @@ mount /dev/disk/by-label/installer /os/installer # 安装 grub2 basearch=$(uname -m) -if [ -d /sys/firmware/efi ]; then - # el7的grub无法启动f38 arm的内核 +if [ -d /sys/firmware/efi/ ]; then + # 注意低版本的grub无法启动f38 arm的内核 # https://forums.fedoraforum.org/showthread.php?330104-aarch64-pxeboot-vmlinuz-file-format-changed-broke-PXE-installs - # shellcheck disable=SC2164 - cd /os/boot/efi - download https://mirrors.aliyun.com/fedora/releases/38/Everything/$basearch/os/images/efiboot.img - mkdir /efiboot - mount -o ro efiboot.img /efiboot - cp -r /efiboot/* /os/boot/efi/ + apk add grub-efi efibootmgr + grub-install --efi-directory=/os/boot/efi --boot-directory=/os/boot + + # 添加 netboot 备用 + cd /os/boot/efi || exit + if [ "$basearch" = aarch64 ]; then + download https://boot.netboot.xyz/ipxe/netboot.xyz-arm64.efi + else + download https://boot.netboot.xyz/ipxe/netboot.xyz.efi + fi else - rpm -i --nodeps https://mirrors.aliyun.com/centos/7/os/x86_64/Packages/grub2-pc-modules-2.02-0.86.el7.centos.noarch.rpm - grub2-install --boot-directory=/os/boot /dev/$xda + apk add grub-bios + grub-install --boot-directory=/os/boot /dev/$xda fi -# 安装 axel -rpm -i --nodeps https://mirrors.aliyun.com/epel/7/$basearch/Packages/a/axel-2.4-9.el7.$basearch.rpm - -if [ -d /sys/firmware/efi ] && [ "$basearch" = "x86_64" ]; then - action='efi' -fi - -# 提取 finalos 到变量 -eval "$(grep -o '\bfinalos\.[^ ]*' /proc/cmdline | sed 's/finalos.//')" - # 重新整理 extra,因为grub会处理掉引号,要重新添加引号 for var in $(grep -o '\bextra\.[^ ]*' /proc/cmdline | xargs); do - extra_cmdline+=" $(echo $var | sed -E "s/(extra\.[^=]*)=(.*)/\1='\2'/")" + extra_cmdline="$extra_cmdline $(echo $var | sed -E "s/(extra\.[^=]*)=(.*)/\1='\2'/")" done -if [ -d /sys/firmware/efi ]; then - grub_cfg=/os/boot/efi/EFI/BOOT/grub.cfg -else - grub_cfg=/os/boot/grub2/grub.cfg -fi +grub_cfg=/os/boot/grub/grub.cfg -# shellcheck disable=SC2154,SC2164 +# 新版grub不区分linux/linuxefi +# shellcheck disable=SC2154 if [ "$distro" = "ubuntu" ]; then - cd /os/installer/ + cd /os/installer/ || exit download $iso ubuntu.iso iso_file=/ubuntu.iso @@ -144,26 +221,25 @@ if [ "$distro" = "ubuntu" ]; then rmmod tpm search --no-floppy --label --set=root installer loopback loop $iso_file - linux (loop)/casper/vmlinuz iso-scan/filename=$iso_file autoinstall cloud-config-url=$ks $extra_cmdline --- + linux (loop)/casper/vmlinuz iso-scan/filename=$iso_file autoinstall noprompt noeject cloud-config-url=$ks $extra_cmdline --- initrd (loop)/casper/initrd } EOF else - cd /os/ + cd /os/ || exit download $vmlinuz download $initrd - cd /os/installer/ + cd /os/installer/ || exit download $squashfs install.img cat <$grub_cfg set timeout=5 menuentry "reinstall" { search --no-floppy --label --set=root os - linux$action /vmlinuz inst.stage2=hd:LABEL=installer:/install.img inst.ks=$ks $extra_cmdline - initrd$action /initrd.img + linux /vmlinuz inst.stage2=hd:LABEL=installer:/install.img inst.ks=$ks $extra_cmdline + initrd /initrd.img } EOF fi reboot -%end diff --git a/ubuntu-storage-early.sh b/ubuntu-storage-early.sh index bab4769..11a73d8 100644 --- a/ubuntu-storage-early.sh +++ b/ubuntu-storage-early.sh @@ -1,21 +1,23 @@ #!/bin/bash -sed -i '$d' /autoinstall.yaml +sed -i -E '/^\.{3}$/d' /autoinstall.yaml +echo 'storage:' >>/autoinstall.yaml + +# 禁用 swap +cat <>/autoinstall.yaml + swap: + size: 0 +EOF + xda=$(lsblk -dn -o NAME | grep -E 'nvme0n1|.da') # 是用 size 寻找分区,number 没什么用 # https://curtin.readthedocs.io/en/latest/topics/storage.html size_os=$(lsblk -bn -o SIZE /dev/disk/by-label/os) if parted /dev/$xda print | grep '^Partition Table' | grep gpt; then - # parted 3.1 on centos7 bug - # https://documentation.suse.com/zh-cn/sles/15/html/SLES-all/cha-expert-partitioner.html#sec-expert-partitioner-tables-gpt - parted /dev/$xda -s 'set 2 msftdata off' # os - parted /dev/$xda -s 'set 3 msftdata off' # installer - # efi if [ -e /dev/disk/by-label/efi ]; then size_efi=$(lsblk -bn -o SIZE /dev/disk/by-label/efi) cat <>/autoinstall.yaml -storage: config: # disk - ptable: gpt @@ -60,7 +62,6 @@ EOF # bios 2t size_biosboot=$(parted /dev/$xda unit b print | grep bios_grub | awk '{print $4}' | sed 's/B$//') cat <>/autoinstall.yaml -storage: config: # disk - ptable: gpt @@ -97,7 +98,6 @@ EOF else # bios cat <>/autoinstall.yaml -storage: config: # disk - ptable: msdos diff --git a/user-data b/user-data index f7b955c..1a7ca76 100644 --- a/user-data +++ b/user-data @@ -17,7 +17,10 @@ autoinstall: mount | grep /isodevice && { losetup -d /dev/loop0; umount -l /isodevice; } || true # 提取 extra.confhome - eval "$(grep -o '\bextra\.[^ ]*' /proc/cmdline | sed 's/\bextra.//')" + prefix=extra + for var in $(grep -o "\b$prefix\.[^ ]*" /proc/cmdline | xargs); do + eval "$(echo $var | sed -E "s/$prefix\.([^=]*)=(.*)/\1='\2'/")" + done # 生成分区信息 curl -L $confhome/ubuntu-storage-early.sh | bash -s @@ -35,7 +38,10 @@ autoinstall: sed -i -E 's/^#(nameserver )/\1/' /etc/resolv.conf # 提取 extra.confhome - eval "$(grep -o '\bextra\.[^ ]*' /proc/cmdline | sed 's/\bextra.//')" + prefix=extra + for var in $(grep -o "\b$prefix\.[^ ]*" /proc/cmdline | xargs); do + eval "$(echo $var | sed -E "s/$prefix\.([^=]*)=(.*)/\1='\2'/")" + done # 下载合并分区脚本 cd /target @@ -43,7 +49,7 @@ autoinstall: # 升级 cloud-init # curtin in-target --target=/target -- apt update - # curtin in-target --target=/target -- apt-get install --only-upgrade cloud-init + # curtin in-target --target=/target -- apt install --only-upgrade cloud-init user-data: runcmd: - |