diff --git a/README.md b/README.md index 78699fb..36d9c25 100644 --- a/README.md +++ b/README.md @@ -1 +1,12 @@ -# reinstall \ No newline at end of file +# reinstall +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 +reboot +``` +Username: `root` + + +Password: `1` + diff --git a/ks-trans.cfg b/ks-trans.cfg new file mode 100644 index 0000000..e687878 --- /dev/null +++ b/ks-trans.cfg @@ -0,0 +1,163 @@ +# shellcheck disable=SC2148 +rescue --nomount +%pre + +exec >/dev/pts/0 2>&1 + +download() { + if command -v axel; then + [ -z $2 ] && save="" || save="-o $2" + axel $1 $save + else + [ -z $2 ] && save="-O" || save="-o $2" + curl -L $1 $save + fi +} + +update_part() { + partprobe + partx -u $1 + udevadm settle +} + +# 找到主硬盘 +xda=$(lsblk -dn -o NAME | grep -E 'nvme0n1|.da') + +# 反激活 lvm +vgchange -an + +# 移除 lsblk 显示的分区 +partx -d /dev/$xda + +disk_size=$(blockdev --getsize64 /dev/$xda) +disk_2t=$((2 * 1024 * 1024 * 1024 * 1024)) + +# 对于红帽系是临时分区表,安装时除了 installer 分区,其他分区会重建为默认的大小 +# 对于ubuntu是最终分区表,因为 ubuntu 的安装器不能调整个别分区,只能重建整个分区表 +# {xda}*1 星号用于 nvme0n1p1 的字母 p +if [ -d /sys/firmware/efi ]; then + # efi + parted /dev/$xda -s -- \ + mklabel gpt \ + mkpart '" "' fat32 1MiB 1025MiB \ + mkpart '" "' ext4 1025MiB -2GiB \ + mkpart '" "' ext4 -2GiB 100% \ + set 1 boot on + update_part /dev/$xda + mkfs.fat -F 32 -n efi /dev/${xda}*1 #1 efi + mkfs.ext4 -L os /dev/${xda}*2 #2 os + mkfs.ext4 -L installer /dev/${xda}*3 #3 installer +elif [ "$disk_size" -ge "$disk_2t" ]; then + # bios 2t + parted /dev/$xda -s -- \ + mklabel gpt \ + mkpart '" "' ext4 1MiB 2MiB \ + mkpart '" "' ext4 2MiB -2GiB \ + mkpart '" "' ext4 -2GiB 100% \ + set 1 bios_grub on + update_part /dev/$xda + echo #1 bios_boot + mkfs.ext4 -L os /dev/${xda}*2 #2 os + mkfs.ext4 -L installer /dev/${xda}*3 #3 installer +else + # bios + parted /dev/$xda -s -- \ + mklabel msdos \ + mkpart primary ext4 1MiB -2GiB \ + mkpart primary ext4 -2GiB 100% \ + set 1 boot on + update_part /dev/$xda + mkfs.ext4 -L os /dev/${xda}*1 #1 os + mkfs.ext4 -L installer /dev/${xda}*2 #2 installer +fi + +# 挂载主分区 +mkdir -p /os +mount /dev/disk/by-label/os /os + +# 挂载其他分区 +mkdir -p /os/boot/efi +mount /dev/disk/by-label/efi /os/boot/efi +mkdir -p /os/installer +mount /dev/disk/by-label/installer /os/installer + +# 安装 grub2 +basearch=$(uname -m) +if [ -d /sys/firmware/efi ]; then + # 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/ +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 +fi + +# 安装 axel +# rpm -i --nodeps https://mirrors.aliyun.com/epel/7/$basearch/Packages/a/axel-2.4-9.el7.$basearch.rpm + +# 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. + +# 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. + +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'/")" +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 + +# shellcheck disable=SC2154,SC2164 +if [ "$distro" = "ubuntu" ]; then + cd /os/installer/ + download $iso ubuntu.iso + + iso_file=/ubuntu.iso + # 正常写法应该是 ds="nocloud-net;s=https://xxx/" 但是甲骨文云的ds更优先,自己的ds根本无访问记录 + # $seed 是 https://xxx/ + cat <$grub_cfg + set timeout=5 + menuentry "reinstall" { + 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 --- + initrd (loop)/casper/initrd + } +EOF +else + cd /os/ + download $vmlinuz + download $initrd + + cd /os/installer/ + 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 + } +EOF +fi +reboot +%end diff --git a/ks.cfg b/ks.cfg new file mode 100644 index 0000000..b234580 --- /dev/null +++ b/ks.cfg @@ -0,0 +1,127 @@ +# shellcheck disable=2148,2215 +# 设置 +keyboard --vckeymap=us --xlayouts='us' +lang en_US.UTF-8 +timezone Asia/Shanghai --utc +rootpw --plaintext 1 +text +reboot +%include /tmp/include-url-command + +# 分区 +ignoredisk --only-use="hda|sda|vda|nvme0n1" +bootloader # 甲骨文x86输出到控制台添加 --append="console=ttyS0,9600" +clearpart --all --initlabel +reqpart # 如果需要,自动创建 efi 或 biosboot 分区 +part / --fstype=ext4 --grow # 不用 xfs 因为不能缩小容量 + +# 软件 +%packages --ignoremissing # el9 minimal.iso fedora Server repo/iso 没有 tuned +@^Minimal Install +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会报错 + +%end + +# 禁用防火墙 +# firewall --disabled + +# 禁用 selinux +selinux --disabled + +# 禁用 kdump +%addon com_redhat_kdump --disable +%end + +############################################## +%pre +touch /tmp/include-packages-for-resize +# 有 installer 分区,表示用了两步安装 +if [ -e /dev/disk/by-label/installer ]; then + # 1g内存下,安装器默认开启了zram ,但安装f38还是不够内存,所以还要开启swap + mkdir /installer + mount /dev/disk/by-label/installer /installer + mount /dev/disk/by-label/installer /installer -o remount,rw + swapfile=/installer/swapfile + if -v fallocate; then + fallocate -l 1GiB $swapfile + else + dd if=/dev/zero of=$swapfile bs=1MiB count=1024 + fi + chmod 0600 $swapfile + mkswap $swapfile + swapon $swapfile + + # 两步安装最后扩容要用的软件 + # feroda 默认不包含 cronie + # cloud-utils-growpart 需要用到 gdisk 处理 gpt 分区 + cat </tmp/include-packages-for-resize + cronie + cloud-utils-growpart + gdisk +EOF +fi + +# 重新整理 extra,因为grub会处理掉引号,要重新添加引号 +# 提取 extra.localtest extra.confhome extra.mirrorlist +for var in $(grep -o '\bextra\.[^ ]*' /proc/cmdline | xargs); do + eval " $(echo $var | sed -E "s/extra\.([^=]*)=(.*)/\1='\2'/")" +done + +# 设置安装源 +include=/tmp/include-url-command +distro=$(awk -F: '{ print $3 }' $include + # echo cdrom >$include +else + echo "url --mirrorlist=$mirrorlist" >$include + # 对于el7/fedora, 添加了 updates repo 才会安装最新的包 + if [ "$releasever" = "7" ] || [ "$distro" = "fedoraproject" ]; then + echo "repo --name=updates" >>$include + fi +fi +%end + +############################################## +%post +# el9/fedora 需手动开启 root ssh 密码登录 +# rootpw --allow-ssh 9.1 以上才支持 +distro=$(awk -F: '{ print $3 }' /etc/ssh/sshd_config.d/01-permitrootlogin.conf +fi + +# 分步安装的系统,要将最后一个分区(installer)合并到系统分区 +if [ -e /dev/disk/by-label/installer ]; then + # 提取 extra.confhome + eval "$(grep -o '\bextra\.[^ ]*' /proc/cmdline | sed 's/\bextra.//')" + + cd / + curl -O $confhome/resize.sh + echo '@reboot root bash /resize.sh' >/etc/cron.d/resize +fi +%end diff --git a/meta-data b/meta-data new file mode 100644 index 0000000..e69de29 diff --git a/reinstall.sh b/reinstall.sh index d59c2f9..6a19d10 100644 --- a/reinstall.sh +++ b/reinstall.sh @@ -1,65 +1,252 @@ #!/bin/bash +confhome=https://raw.githubusercontent.com/bin456789/reinstall/main +localtest_confhome=http://192.168.253.1 -# todo 设置各种参数,例如是否自动安装 -localtest=0 -if [ $localtest == 1 ]; then - vmlinuz=http://192.168.43.139/images/pxeboot/vmlinuz - initrd=http://192.168.43.139/images/pxeboot/initrd.img - squashfs=http://192.168.43.139/LiveOS/squashfs.img - ks=http://192.168.43.139/ks-cd.cfg -else - site=$(curl -L "http://mirrorlist.centos.org/?release=7&repo=os&arch=x86_64" | head -1) - vmlinuz=${site}images/pxeboot/vmlinuz - initrd=${site}images/pxeboot/initrd.img - squashfs=${site}LiveOS/squashfs.img +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" + exit 1 +} - ks=https://xxx.com/ks.cfg +is_in_china() { + # https://geoip.ubuntu.com/lookup + curl -L https://geoip.fedoraproject.org/city | grep -w CN +} + +setos() { + step=$1 + distro=$2 + releasever=$3 + ks=$4 + vault=$5 + + setos_ubuntu() { + if [ "$localtest" = 1 ]; then + mirror=$confhome/ + eval ${step}_ks=$confhome/$ks + else + if is_in_china; then + case "$basearch" in + "x86_64") mirror=https://mirrors.aliyun.com/ubuntu-releases/$releasever/ ;; + "aarch64") mirror=https://mirrors.aliyun.com/ubuntu-cdimage/releases/$releasever/release/ ;; + esac + else + case "$basearch" in + "x86_64") mirror=https://releases.ubuntu.com/$releasever/ ;; + "aarch64") mirror=https://cdimage.ubuntu.com/releases/$releasever/release/ ;; + esac + fi + eval ${step}_ks=$confhome/user-data + fi + + case "$basearch" in + "x86_64") arch=amd64 ;; + "aarch64") arch=arm64 ;; + esac + + filename=$(curl $mirror | grep -oP "ubuntu-$releasever.*?-live-server-$arch.iso" | head -1) + eval ${step}_iso=$mirror$filename + eval ${step}_distro=ubuntu + } + + setos_rh() { + 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" ;; + 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 + fi + + eval ${step}_distro=${distro} + eval ${step}_vmlinuz=${mirror}images/pxeboot/vmlinuz + eval ${step}_initrd=${mirror}images/pxeboot/initrd.img + eval ${step}_squashfs=${mirror}images/install.img + + if [ "$releasever" = 7 ]; then + eval ${step}_squashfs=${mirror}LiveOS/squashfs.img + fi + } + + if [ "$distro" = "ubuntu" ]; then + setos_ubuntu + else + setos_rh + fi +} + +if [ "$EUID" -ne 0 ]; then + echo "Please run as root." + exit 1 fi -# 获取系统盘信息 -root_name=$(lsblk -l -o NAME,UUID,TYPE,MOUNTPOINT | tr -s ' ' | grep '/$' | cut -d ' ' -f1) -root_uuid=$(lsblk -l -o NAME,UUID,TYPE,MOUNTPOINT | tr -s ' ' | grep '/$' | cut -d ' ' -f2) -root_type=$(lsblk -l -o NAME,UUID,TYPE,MOUNTPOINT | tr -s ' ' | grep '/$' | cut -d ' ' -f3) +opts=$(getopt -a -n $0 --options l --long localtest -- "$@") +if [ "$?" != 0 ]; then + usage_and_exit +fi -# 清除之前的自定义启动条目 -sed -i '3,$d' /etc/grub.d/40_custom +eval set -- "$opts" +while true; do + case "$1" in + -l | --localtest) + localtest=1 + confhome=$localtest_confhome + shift + ;; + --) + shift + break + ;; + *) + echo "Unexpected option: $1." + usage_and_exit + ;; + 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 + +install_pkg curl +distro=$(echo $finalos | cut -d: -f1) +releasever=$(echo $finalos | cut -d: -f2) +basearch=$(uname -m) + +# 以下目标系统需要两步安装 +# ubuntu +# el8/9/fedora 任何架构 <2g +# el7 aarch64 <1.5g +# shellcheck disable=SC2154 +if [ $distro = "ubuntu" ] || + { [ $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 + setos finalos $distro $releasever $ks + setos nextos centos 7 ks-trans.cfg 1 +else + setos nextos $distro $releasever ks.cfg +fi # 下载启动内核 -cd / -curl -LO $vmlinuz -curl -LO $initrd -cd - +# shellcheck disable=SC2154 +{ + cd / + curl -LO $nextos_vmlinuz + curl -LO $nextos_initrd + touch reinstall.mark +} -if [ -d /sys/firmware/efi ]; then +# 转换 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}" + 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'" + fi + fi +} + +# arm64 不需要添加 efi 字样 +if [ -d /sys/firmware/efi ] && [ "$basearch" = x86_64 ]; then action='efi' -else - action='16' fi -if [ $root_type == "lvm" ]; then - cat <>/etc/grub.d/40_custom +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) + +custom_cfg=$grub_cfg_dir/custom.cfg +echo $custom_cfg +# shellcheck disable=SC2154 +cat <>/etc/grub.d/40_custom -menuentry "reinstall" { - insmod xfs - search --no-floppy --fs-uuid --set=root $root_uuid - linux$action /vmlinuz root=live:$squashfs inst.ks=$ks - initrd$action /initrd.img - } -EOF -fi - -grub_cfg=$(find /boot -type f -name grub.cfg) -grub-mkconfig -o $grub_cfg || grub2-mkconfig -o $grub_cfg -grub-reboot reinstall || grub2-reboot reinstall -cat $grub_cfg -# reboot +$(command -v grub-reboot grub2-reboot) reinstall +echo "Please reboot to begin the installation." diff --git a/resize.sh b/resize.sh new file mode 100644 index 0000000..1c3d1af --- /dev/null +++ b/resize.sh @@ -0,0 +1,44 @@ +#!/bin/bash +PATH="/usr/sbin:/usr/bin" + +update_part() { + partprobe + partx -u $1 + udevadm settle +} + +# rh 自带 fdisk parted +# ubuntu 自带 fdisk growpart + +# 找出主硬盘 +xda=$(lsblk -dn -o NAME | grep -E 'nvme0n1|.da') + +# 删除 installer 分区 +installer_num=$(readlink -f /dev/disk/by-label/installer | grep -o '[0-9]*$') +if [ -n "$installer_num" ]; then + # 要添加 LC_NUMERIC 或者将%转义成\%才能在cron里正确运行 + LC_NUMERIC=en_US.utf8 + printf "d\n%s\nw" "$installer_num" | fdisk /dev/$xda + update_part /dev/$xda +fi + +# 找出现在的最后一个分区,也就是系统分区 +# el7 的 lsblk 没有 --sort,所以用其他方法 +# shellcheck disable=2012 +part_num=$(ls -1v /dev/$xda* | tail -1 | grep -o '[0-9]*$') +part_fstype=$(lsblk -no FSTYPE /dev/$xda$part_num) + +# 扩容分区 +# rh 7 不能用parted在线扩容,而fdisk扩容会改变 PARTUUID,所以用 growpart +# printf 'yes\n100%%' | parted /dev/$xda resizepart $part_num ---pretend-input-tty +growpart /dev/$xda $part_num +update_part /dev/$xda + +# 扩容最后一个分区的文件系统 +case $part_fstype in +xfs) xfs_growfs / ;; +ext*) resize2fs /dev/$xda$part_num ;; +esac + +# 删除脚本自身 +rm -f /resize.sh /etc/cron.d/resize diff --git a/ubuntu-storage-early.sh b/ubuntu-storage-early.sh new file mode 100644 index 0000000..c8549b7 --- /dev/null +++ b/ubuntu-storage-early.sh @@ -0,0 +1,127 @@ +#!/bin/bash +sed -i '$d' /autoinstall.yaml +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/sda 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 + path: /dev/$xda + preserve: true + type: disk + id: disk-xda + # efi 分区 + - device: disk-xda + size: $size_efi + number: 1 + preserve: true + grub_device: true + type: partition + id: partition-efi + - fstype: fat32 + volume: partition-efi + type: format + id: format-efi + # os 分区 + - device: disk-xda + size: $size_os + number: 2 + preserve: true + type: partition + id: partition-os + - fstype: ext4 + volume: partition-os + type: format + id: format-os + # mount + - path: / + device: format-os + type: mount + id: mount-os + - path: /boot/efi + device: format-efi + type: mount + id: mount-efi +EOF + else + # 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 + path: /dev/$xda + preserve: true + grub_device: true + type: disk + id: disk-xda + # biosboot 分区 + - device: disk-xda + size: $size_biosboot + number: 1 + preserve: true + type: partition + id: partition-biosboot + # os 分区 + - device: disk-xda + size: $size_os + number: 2 + preserve: true + type: partition + id: partition-os + - fstype: ext4 + volume: partition-os + type: format + id: format-os + # mount + - path: / + device: format-os + type: mount + id: mount-os +EOF + fi +else + # bios + cat <>/autoinstall.yaml +storage: + config: + # disk + - ptable: msdos + path: /dev/$xda + preserve: true + grub_device: true + type: disk + id: disk-xda + # os 分区 + - device: disk-xda + size: $size_os + number: 1 + preserve: true + type: partition + id: partition-os + - fstype: ext4 + volume: partition-os + type: format + id: format-os + # mount + - path: / + device: format-os + type: mount + id: mount-os +EOF +fi +echo ... >>/autoinstall.yaml diff --git a/user-data b/user-data new file mode 100644 index 0000000..b9c6e87 --- /dev/null +++ b/user-data @@ -0,0 +1,64 @@ +#cloud-config +# 顺序 early-commands > 安装系统 > late-commands > 重启进入系统 > cloud-init: runcmd > cloud-init: 其他 +autoinstall: + version: 1 + source: + id: ubuntu-server-minimal + search_drivers: false + timezone: Asia/Shanghai + ssh: + allow-pw: true + authorized-keys: [] + install-server: true + early-commands: + - | + # 解决 20.04 不能识别硬盘 + # https://askubuntu.com/questions/1302392/ubuntu-server-20-04-setup-stuck-at-block-probing-did-not-discover-any-disks + mount | grep /isodevice && { losetup -d /dev/loop0; umount -l /isodevice; } || true + + # 提取 extra.confhome + eval "$(grep -o '\bextra\.[^ ]*' /proc/cmdline | sed 's/\bextra.//')" + + # 生成分区信息 + curl -L $confhome/ubuntu-storage-early.sh | bash -s + + # 禁用 DNS 强制离线安装内核和跳过最后的更新 + # 但安装器会配置时区和写入最近的mirror到/etc/apt/sources.list 所以要提前解析 + echo $(dig +short geoip.ubuntu.com | grep -v '\.$' | head -1) geoip.ubuntu.com >>/etc/hosts + sed -i -E 's/(^nameserver )/#\1/' /etc/resolv.conf + late-commands: + - | + # root ssh 登录 + echo "PermitRootLogin yes" >/target/etc/ssh/sshd_config.d/01-permitrootlogin.conf + + # 还原 DNS + sed -i -E 's/^#(nameserver )/\1/' /etc/resolv.conf + + # 提取 extra.confhome + eval "$(grep -o '\bextra\.[^ ]*' /proc/cmdline | sed 's/\bextra.//')" + + # 下载合并分区脚本 + cd /target + curl -O $confhome/resize.sh + + # 升级 cloud-init + # curtin in-target --target=/target -- apt update + # curtin in-target --target=/target -- apt-get install --only-upgrade cloud-init + user-data: + runcmd: + - | + # 合并分区 + bash /resize.sh + disable_root: false + users: + - name: root + lock_passwd: false + chpasswd: + expire: false + # 20.04 arm 需要 + list: | + root:1 + users: + - name: root + password: 1 + type: text diff --git a/vendor-data b/vendor-data new file mode 100644 index 0000000..e69de29