2023-05-13 00:14:46 +08:00
|
|
|
|
#!/bin/ash
|
|
|
|
|
# shellcheck shell=dash
|
2023-07-06 21:45:27 +08:00
|
|
|
|
# shellcheck disable=SC3047,SC3036,SC3010
|
2023-05-13 00:14:46 +08:00
|
|
|
|
# alpine 默认使用 busybox ash
|
|
|
|
|
|
2023-06-18 21:27:22 +08:00
|
|
|
|
# 命令出错退出脚本,进入到登录界面,防止失联
|
|
|
|
|
# TODO: neet more test
|
|
|
|
|
set -eE
|
|
|
|
|
|
2023-05-13 00:14:46 +08:00
|
|
|
|
# 显示输出到前台
|
|
|
|
|
# 似乎script更优雅,但 alpine 不带 script 命令
|
|
|
|
|
# script -f/dev/tty0
|
|
|
|
|
exec >/dev/tty0 2>&1
|
2023-07-03 23:11:10 +08:00
|
|
|
|
trap 'error line $LINENO return $?' ERR
|
2023-06-18 21:27:22 +08:00
|
|
|
|
|
|
|
|
|
catch() {
|
|
|
|
|
if [ "$1" != "0" ]; then
|
|
|
|
|
error "Error $1 occurred on $2"
|
|
|
|
|
fi
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
error() {
|
|
|
|
|
color='\e[31m'
|
|
|
|
|
plain='\e[0m'
|
|
|
|
|
echo -e "${color}Error: $*$plain"
|
|
|
|
|
}
|
2023-05-13 00:14:46 +08:00
|
|
|
|
|
2023-05-25 20:15:12 +08:00
|
|
|
|
add_community_repo() {
|
2023-07-05 21:57:27 +08:00
|
|
|
|
if ! grep -x 'http.*/community' /etc/apk/repositories; then
|
|
|
|
|
alpine_ver=$(cut -d. -f1,2 </etc/alpine-release)
|
|
|
|
|
echo http://dl-cdn.alpinelinux.org/alpine/v$alpine_ver/community >>/etc/apk/repositories
|
|
|
|
|
fi
|
2023-05-25 20:15:12 +08:00
|
|
|
|
}
|
|
|
|
|
|
2023-07-03 23:11:10 +08:00
|
|
|
|
cp() {
|
|
|
|
|
# 防止 alias cp='cp -i'
|
|
|
|
|
command cp "$@"
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-18 21:27:22 +08:00
|
|
|
|
download() {
|
2023-07-03 23:11:10 +08:00
|
|
|
|
url=$1
|
|
|
|
|
file=$2
|
|
|
|
|
echo $url
|
2023-06-18 21:27:22 +08:00
|
|
|
|
|
|
|
|
|
# 阿里云禁止 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
|
|
|
|
|
|
2023-07-03 23:11:10 +08:00
|
|
|
|
# axel 在 lightsail 上会占用大量cpu
|
|
|
|
|
# 先用 aria2 下载
|
2023-07-05 21:54:37 +08:00
|
|
|
|
[ -z $file ] && save="" || save="-d / -o $file"
|
2023-07-06 21:39:32 +08:00
|
|
|
|
if ! aria2c -x4 --allow-overwrite=true $url $save; then
|
2023-06-18 21:27:22 +08:00
|
|
|
|
# 出错再用 curl
|
2023-07-03 23:11:10 +08:00
|
|
|
|
[ -z $file ] && save="-O" || save="-o $file"
|
|
|
|
|
curl -L $url $save
|
2023-06-18 21:27:22 +08:00
|
|
|
|
fi
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
update_part() {
|
|
|
|
|
hdparm -z $1 || true
|
|
|
|
|
partprobe $1 || true
|
|
|
|
|
partx -u $1 || true
|
|
|
|
|
udevadm settle || true
|
|
|
|
|
echo 1 >/sys/block/${1#/dev/}/device/rescan || true
|
|
|
|
|
} 2>/dev/null
|
|
|
|
|
|
2023-05-13 00:14:46 +08:00
|
|
|
|
# 提取 finalos/extra 到变量
|
|
|
|
|
for prefix in finalos extra; do
|
2023-05-25 20:15:12 +08:00
|
|
|
|
while read -r line; do
|
|
|
|
|
if [ -n "$line" ]; then
|
|
|
|
|
key=$(echo $line | cut -d= -f1)
|
|
|
|
|
value=$(echo $line | cut -d= -f2-)
|
|
|
|
|
eval "$key='$value'"
|
|
|
|
|
fi
|
|
|
|
|
done <<EOF
|
|
|
|
|
$(xargs -n1 </proc/cmdline | grep "^$prefix" | sed "s/^$prefix\.//")
|
|
|
|
|
EOF
|
2023-05-13 00:14:46 +08:00
|
|
|
|
done
|
2023-05-03 22:22:21 +08:00
|
|
|
|
|
2023-05-13 00:14:46 +08:00
|
|
|
|
# 找到主硬盘
|
|
|
|
|
# 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
|
|
|
|
|
|
2023-06-18 21:27:22 +08:00
|
|
|
|
# shellcheck disable=SC2154
|
|
|
|
|
if [ "$sleep" = 1 ]; then
|
|
|
|
|
cd /
|
|
|
|
|
sleep infinity
|
|
|
|
|
fi
|
|
|
|
|
|
2023-05-13 00:14:46 +08:00
|
|
|
|
# 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
|
2023-06-18 21:27:22 +08:00
|
|
|
|
setup-ntp chrony || true
|
2023-05-13 00:14:46 +08:00
|
|
|
|
|
|
|
|
|
# 在 arm netboot initramfs init 中
|
|
|
|
|
# 如果识别到rtc硬件,就往系统添加hwclock服务,否则添加swclock
|
|
|
|
|
# 这个设置也被复制到安装的系统中
|
|
|
|
|
# 但是从initramfs chroot到真正的系统后,是能识别rtc硬件的
|
|
|
|
|
# 所以我们手动改用hwclock修复这个问题
|
2023-06-18 21:27:22 +08:00
|
|
|
|
rc-update del swclock boot || true
|
|
|
|
|
rc-update add hwclock boot || true
|
2023-05-13 00:14:46 +08:00
|
|
|
|
|
|
|
|
|
# 通过 setup-alpine 安装会多启用几个服务
|
|
|
|
|
# https://github.com/alpinelinux/alpine-conf/blob/c5131e9a038b09881d3d44fb35e86851e406c756/setup-alpine.in#L189
|
|
|
|
|
# acpid | default
|
|
|
|
|
# crond | default
|
|
|
|
|
# seedrng | boot
|
|
|
|
|
|
|
|
|
|
# 添加 virt-what 用到的社区仓库
|
2023-05-25 20:15:12 +08:00
|
|
|
|
add_community_repo
|
2023-05-13 00:14:46 +08:00
|
|
|
|
|
|
|
|
|
# 如果是 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
|
2023-06-04 19:12:57 +08:00
|
|
|
|
|
|
|
|
|
elif [ "$distro" = "dd" ]; then
|
2023-06-05 19:45:07 +08:00
|
|
|
|
case "$img_type" in
|
2023-06-05 19:50:21 +08:00
|
|
|
|
gzip) prog=gzip ;;
|
2023-06-04 19:12:57 +08:00
|
|
|
|
xz) prog=xz ;;
|
|
|
|
|
esac
|
|
|
|
|
|
|
|
|
|
if [ -n "$prog" ]; then
|
|
|
|
|
# alpine busybox 自带 gzip xz,但官方版也许性能更好
|
2023-06-18 21:27:22 +08:00
|
|
|
|
# wget -O- $img | $prog -dc >/dev/$xda
|
2023-06-04 19:12:57 +08:00
|
|
|
|
apk add curl $prog
|
2023-07-03 13:51:59 +08:00
|
|
|
|
# curl -L $img | $prog -dc | dd of=/dev/$xda bs=1M
|
2023-06-05 19:45:07 +08:00
|
|
|
|
curl -L $img | $prog -dc >/dev/$xda
|
2023-06-18 21:27:22 +08:00
|
|
|
|
sync
|
2023-06-04 19:12:57 +08:00
|
|
|
|
else
|
|
|
|
|
echo 'Not supported'
|
|
|
|
|
sleep 1m
|
|
|
|
|
fi
|
2023-06-18 21:27:22 +08:00
|
|
|
|
if [ "$sleep" = 2 ]; then
|
|
|
|
|
cd /
|
|
|
|
|
sleep infinity
|
|
|
|
|
fi
|
2023-06-04 19:12:57 +08:00
|
|
|
|
exec reboot
|
2023-05-13 00:14:46 +08:00
|
|
|
|
fi
|
2023-05-03 22:22:21 +08:00
|
|
|
|
|
2023-06-18 21:27:22 +08:00
|
|
|
|
# 目标系统非 alpine 和 dd
|
|
|
|
|
# 脚本开始
|
2023-07-03 23:11:10 +08:00
|
|
|
|
add_community_repo
|
|
|
|
|
if ! apk add util-linux aria2 grub udev hdparm e2fsprogs curl parted; then
|
2023-05-13 00:14:46 +08:00
|
|
|
|
echo 'Unable to install package!'
|
|
|
|
|
sleep 1m
|
|
|
|
|
exec reboot
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
# 打开dev才能刷新分区名
|
|
|
|
|
rc-service udev start
|
2023-05-03 22:22:21 +08:00
|
|
|
|
|
|
|
|
|
# 反激活 lvm
|
2023-05-13 00:14:46 +08:00
|
|
|
|
# alpine live 不需要
|
|
|
|
|
false && vgchange -an
|
2023-05-03 22:22:21 +08:00
|
|
|
|
|
|
|
|
|
# 移除 lsblk 显示的分区
|
|
|
|
|
partx -d /dev/$xda
|
|
|
|
|
|
|
|
|
|
disk_size=$(blockdev --getsize64 /dev/$xda)
|
|
|
|
|
disk_2t=$((2 * 1024 * 1024 * 1024 * 1024))
|
|
|
|
|
|
2023-05-28 00:52:48 +08:00
|
|
|
|
# xda*1 星号用于 nvme0n1p1 的字母 p
|
2023-05-25 20:15:12 +08:00
|
|
|
|
if [ "$distro" = windows ]; then
|
2023-05-28 00:52:48 +08:00
|
|
|
|
add_community_repo
|
2023-06-04 19:02:06 +08:00
|
|
|
|
apk add ntfs-3g ntfs-3g-progs fuse3 virt-what wimlib rsync dos2unix
|
2023-05-28 00:52:48 +08:00
|
|
|
|
modprobe fuse
|
2023-05-25 20:15:12 +08:00
|
|
|
|
if [ -d /sys/firmware/efi ]; then
|
2023-05-28 00:52:48 +08:00
|
|
|
|
# efi
|
|
|
|
|
apk add dosfstools
|
2023-05-25 20:15:12 +08:00
|
|
|
|
parted /dev/$xda -s -- \
|
|
|
|
|
mklabel gpt \
|
|
|
|
|
mkpart '" "' fat32 1MiB 1025MiB \
|
|
|
|
|
mkpart '" "' fat32 1025MiB 1041MiB \
|
|
|
|
|
mkpart '" "' ext4 1041MiB -6GiB \
|
|
|
|
|
mkpart '" "' ntfs -6GiB 100% \
|
|
|
|
|
set 1 boot on \
|
|
|
|
|
set 2 msftres on \
|
|
|
|
|
set 3 msftdata on
|
|
|
|
|
update_part /dev/$xda
|
2023-05-28 00:52:48 +08:00
|
|
|
|
mkfs.fat -F 32 -n efi /dev/$xda*1 #1 efi
|
|
|
|
|
echo #2 msr
|
|
|
|
|
mkfs.ext4 -F -L os /dev/$xda*3 #3 os
|
|
|
|
|
mkfs.ntfs -f -F -L installer /dev/$xda*4 #4 installer
|
2023-05-25 20:15:12 +08:00
|
|
|
|
else
|
2023-05-28 00:52:48 +08:00
|
|
|
|
# bios
|
|
|
|
|
parted /dev/$xda -s -- \
|
|
|
|
|
mklabel msdos \
|
|
|
|
|
mkpart primary ntfs 1MiB -6GiB \
|
|
|
|
|
mkpart primary ntfs -6GiB 100% \
|
|
|
|
|
set 1 boot on
|
|
|
|
|
update_part /dev/$xda
|
|
|
|
|
mkfs.ext4 -F -L os /dev/$xda*1 #1 os
|
|
|
|
|
mkfs.ntfs -f -F -L installer /dev/$xda*2 #2 installer
|
2023-05-25 20:15:12 +08:00
|
|
|
|
fi
|
2023-05-03 22:22:21 +08:00
|
|
|
|
else
|
2023-05-28 00:52:48 +08:00
|
|
|
|
# 对于红帽系是临时分区表,安装时除了 installer 分区,其他分区会重建为默认的大小
|
|
|
|
|
# 对于ubuntu是最终分区表,因为 ubuntu 的安装器不能调整个别分区,只能重建整个分区表
|
2023-05-25 20:15:12 +08:00
|
|
|
|
if [ -d /sys/firmware/efi ]; then
|
|
|
|
|
# efi
|
|
|
|
|
apk add dosfstools
|
|
|
|
|
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
|
2023-05-28 00:52:48 +08:00
|
|
|
|
mkfs.fat -F 32 -n efi /dev/$xda*1 #1 efi
|
|
|
|
|
mkfs.ext4 -F -L os /dev/$xda*2 #2 os
|
|
|
|
|
mkfs.ext4 -F -L installer /dev/$xda*3 #3 installer
|
2023-05-25 20:15:12 +08:00
|
|
|
|
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
|
2023-05-28 00:52:48 +08:00
|
|
|
|
echo #1 bios_boot
|
|
|
|
|
mkfs.ext4 -F -L os /dev/$xda*2 #2 os
|
|
|
|
|
mkfs.ext4 -F -L installer /dev/$xda*3 #3 installer
|
2023-05-25 20:15:12 +08:00
|
|
|
|
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
|
2023-05-28 00:52:48 +08:00
|
|
|
|
mkfs.ext4 -F -L os /dev/$xda*1 #1 os
|
|
|
|
|
mkfs.ext4 -F -L installer /dev/$xda*2 #2 installer
|
2023-05-25 20:15:12 +08:00
|
|
|
|
fi
|
2023-05-03 22:22:21 +08:00
|
|
|
|
fi
|
2023-05-25 20:15:12 +08:00
|
|
|
|
|
2023-05-07 21:12:26 +08:00
|
|
|
|
update_part /dev/$xda
|
2023-05-03 22:22:21 +08:00
|
|
|
|
|
|
|
|
|
# 挂载主分区
|
|
|
|
|
mkdir -p /os
|
|
|
|
|
mount /dev/disk/by-label/os /os
|
|
|
|
|
|
|
|
|
|
# 挂载其他分区
|
|
|
|
|
mkdir -p /os/boot/efi
|
2023-05-28 00:52:48 +08:00
|
|
|
|
if [ -d /sys/firmware/efi/ ]; then
|
|
|
|
|
mount /dev/disk/by-label/efi /os/boot/efi
|
|
|
|
|
fi
|
2023-05-03 22:22:21 +08:00
|
|
|
|
mkdir -p /os/installer
|
|
|
|
|
mount /dev/disk/by-label/installer /os/installer
|
|
|
|
|
|
2023-05-25 20:15:12 +08:00
|
|
|
|
# shellcheck disable=SC2154
|
2023-05-28 00:52:48 +08:00
|
|
|
|
if [ "$distro" = "windows" ]; then
|
2023-05-25 20:15:12 +08:00
|
|
|
|
download $iso /os/windows.iso
|
2023-06-21 23:34:25 +08:00
|
|
|
|
mkdir -p /iso
|
2023-05-25 20:15:12 +08:00
|
|
|
|
mount /os/windows.iso /iso
|
|
|
|
|
|
2023-07-06 21:45:27 +08:00
|
|
|
|
# 从iso复制文件
|
|
|
|
|
# efi: 复制boot开头的文件+efi目录到efi分区,复制iso全部文件(除了boot.wim)到installer分区
|
|
|
|
|
# bios: 复制iso全部文件到installer分区
|
|
|
|
|
if [ -d /sys/firmware/efi/ ]; then
|
|
|
|
|
mkdir -p /os/boot/efi/sources/
|
|
|
|
|
cp -rv /iso/boot* /os/boot/efi/
|
|
|
|
|
cp -rv /iso/efi/ /os/boot/efi/
|
|
|
|
|
cp -rv /iso/sources/boot.wim /os/boot/efi/sources/
|
|
|
|
|
rsync -rv --exclude=/sources/boot.wim /iso/* /os/installer/
|
|
|
|
|
boot_wim=/os/boot/efi/sources/boot.wim
|
|
|
|
|
else
|
|
|
|
|
rsync -rv /iso/* /os/installer/
|
|
|
|
|
boot_wim=/os/installer/sources/boot.wim
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
if [ -e /os/installer/sources/install.esd ]; then
|
|
|
|
|
install_wim=/os/installer/sources/install.esd
|
|
|
|
|
else
|
|
|
|
|
install_wim=/os/installer/sources/install.wim
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
# 匹配映像版本
|
|
|
|
|
# 需要整行匹配,因为要区分 Windows 10 Pro 和 Windows 10 Pro for Workstations
|
|
|
|
|
# TODO: 如果无法匹配,等待用户输入?安装第一个?
|
|
|
|
|
image_count=$(wiminfo $install_wim | grep "Image Count:" | cut -d: -f2 | xargs)
|
|
|
|
|
if [ "$image_count" = 1 ]; then
|
|
|
|
|
# 只有一个版本就使用第一个版本
|
|
|
|
|
image_name=$(wiminfo $install_wim | grep -ix "Name:[[:blank:]]*.*" | cut -d: -f2 | xargs)
|
|
|
|
|
else
|
|
|
|
|
# 否则改成正确的大小写
|
|
|
|
|
image_name=$(wiminfo $install_wim | grep -ix "Name:[[:blank:]]*$image_name" | cut -d: -f2 | xargs)
|
|
|
|
|
fi
|
|
|
|
|
|
2023-07-03 23:11:10 +08:00
|
|
|
|
# 变量名 使用场景
|
|
|
|
|
# arch_uname uname -m x86_64 aarch64
|
|
|
|
|
# arch_wim wiminfo x86 x86_64 ARM64
|
|
|
|
|
# arch virtio驱动/unattend.xml x86 amd64 arm64
|
|
|
|
|
# arch_xen xen驱动 x86 x64
|
2023-06-05 19:54:00 +08:00
|
|
|
|
|
|
|
|
|
# 将 wim 的 arch 转为驱动和应答文件的 arch
|
2023-07-06 21:45:27 +08:00
|
|
|
|
arch_wim=$(wiminfo $install_wim 1 | grep Architecture: | awk '{print $2}' | tr '[:upper:]' '[:lower:]')
|
2023-06-05 19:54:00 +08:00
|
|
|
|
case "$arch_wim" in
|
2023-07-03 23:11:10 +08:00
|
|
|
|
x86)
|
|
|
|
|
arch=x86
|
|
|
|
|
arch_xen=x86
|
|
|
|
|
;;
|
|
|
|
|
x86_64)
|
|
|
|
|
arch=amd64
|
|
|
|
|
arch_xen=x64
|
|
|
|
|
;;
|
|
|
|
|
arm64)
|
|
|
|
|
arch=arm64
|
|
|
|
|
arch_xen= # xen 没有 arm64 驱动
|
|
|
|
|
;;
|
2023-06-05 19:54:00 +08:00
|
|
|
|
esac
|
|
|
|
|
|
|
|
|
|
# virt-what 要用最新版
|
|
|
|
|
# vultr 1G High Frequency LAX 实际上是 kvm
|
|
|
|
|
# debian 11 virt-what 1.19 显示为 hyperv qemu
|
|
|
|
|
# debian 11 systemd-detect-virt 显示为 microsoft
|
|
|
|
|
# alpine virt-what 1.25 显示为 kvm
|
2023-07-06 21:45:27 +08:00
|
|
|
|
# 所以不要在原系统上判断具体虚拟化环境
|
|
|
|
|
|
|
|
|
|
# lscpu 也可查看虚拟化环境,但 alpine on lightsail 运行结果为 Microsoft
|
|
|
|
|
# 猜测 lscpu 只参考了 cpuid 没参考 dmi
|
2023-06-05 19:54:00 +08:00
|
|
|
|
|
2023-05-25 20:15:12 +08:00
|
|
|
|
# 下载 virtio 驱动
|
2023-07-03 23:11:10 +08:00
|
|
|
|
# virt-what 可能会输出多行结果,因此用 grep
|
|
|
|
|
drv=/os/drivers
|
|
|
|
|
mkdir -p $drv
|
|
|
|
|
if virt-what | grep aws &&
|
|
|
|
|
virt-what | grep kvm &&
|
2023-07-05 21:40:00 +08:00
|
|
|
|
[ "$arch_wim" = x86_64 ]; then
|
2023-07-03 23:11:10 +08:00
|
|
|
|
# aws nitro
|
2023-07-05 21:40:00 +08:00
|
|
|
|
# 只有 x64 位驱动
|
2023-07-03 13:51:59 +08:00
|
|
|
|
# https://docs.aws.amazon.com/zh_cn/AWSEC2/latest/WindowsGuide/migrating-latest-types.html
|
|
|
|
|
apk add unzip
|
2023-07-03 23:11:10 +08:00
|
|
|
|
download https://s3.amazonaws.com/ec2-windows-drivers-downloads/NVMe/Latest/AWSNVMe.zip $drv/AWSNVMe.zip
|
|
|
|
|
unzip -o -d $drv/aws/ $drv/AWSNVMe.zip
|
|
|
|
|
download https://s3.amazonaws.com/ec2-windows-drivers-downloads/ENA/Latest/AwsEnaNetworkDriver.zip $drv/AwsEnaNetworkDriver.zip
|
|
|
|
|
unzip -o -d $drv/aws/ $drv/AwsEnaNetworkDriver.zip
|
|
|
|
|
|
|
|
|
|
elif virt-what | grep aws &&
|
|
|
|
|
virt-what | grep xen &&
|
2023-07-05 21:40:00 +08:00
|
|
|
|
[ "$arch_wim" = x86_64 ]; then
|
2023-07-03 23:11:10 +08:00
|
|
|
|
# aws xen
|
|
|
|
|
# 只有 64 位驱动
|
|
|
|
|
# 未测试
|
|
|
|
|
# https://docs.aws.amazon.com/zh_cn/AWSEC2/latest/WindowsGuide/Upgrading_PV_drivers.html
|
|
|
|
|
apk add unzip msitools
|
|
|
|
|
download https://s3.amazonaws.com/ec2-windows-drivers-downloads/AWSPV/Latest/AWSPVDriver.zip $drv/AWSPVDriver.zip
|
|
|
|
|
unzip -o -d $drv $drv/AWSPVDriver.zip
|
|
|
|
|
msiextract $drv/AWSPVDriverSetup.msi -C $drv
|
|
|
|
|
mkdir -p $drv/aws/
|
|
|
|
|
cp -rf $drv/.Drivers/* $drv/aws/
|
|
|
|
|
|
2023-07-05 21:40:00 +08:00
|
|
|
|
elif virt-what | grep xen &&
|
|
|
|
|
[ "$arch_wim" != arm64 ]; then
|
2023-07-03 23:11:10 +08:00
|
|
|
|
# xen
|
2023-07-05 21:40:00 +08:00
|
|
|
|
# 有 x86 x64,没arm64驱动
|
2023-07-03 23:11:10 +08:00
|
|
|
|
# 未测试
|
|
|
|
|
# https://xenbits.xenproject.org/pvdrivers/win/
|
|
|
|
|
ver='9.0.0'
|
|
|
|
|
parts='xenbus xencons xenhid xeniface xennet xenvbd xenvif xenvkbd'
|
|
|
|
|
mkdir -p $drv/xen/
|
|
|
|
|
for part in $parts; do
|
|
|
|
|
download https://xenbits.xenproject.org/pvdrivers/win/$ver/$part.tar $drv/$part.tar
|
|
|
|
|
tar -xf $drv/$part.tar -C $drv/xen/
|
|
|
|
|
done
|
|
|
|
|
|
2023-07-03 13:51:59 +08:00
|
|
|
|
elif virt-what | grep kvm; then
|
2023-07-03 23:11:10 +08:00
|
|
|
|
# virtio
|
2023-07-05 21:40:00 +08:00
|
|
|
|
# x86 x64 arm64 都有
|
2023-07-03 23:11:10 +08:00
|
|
|
|
# https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/stable-virtio/
|
2023-05-25 20:15:12 +08:00
|
|
|
|
case $(echo "$image_name" | tr '[:upper:]' '[:lower:]') in
|
|
|
|
|
'windows server 2022'*) sys=2k22 ;;
|
|
|
|
|
'windows server 2019'*) sys=2k19 ;;
|
|
|
|
|
'windows server 2016'*) sys=2k16 ;;
|
|
|
|
|
'windows server 2012 R2'*) sys=2k12R2 ;;
|
|
|
|
|
'windows server 2012'*) sys=2k12 ;;
|
|
|
|
|
'windows server 2008 R2'*) sys=2k8R2 ;;
|
|
|
|
|
'windows server 2008'*) sys=2k8 ;;
|
|
|
|
|
'windows 11'*) sys=w11 ;;
|
|
|
|
|
'windows 10'*) sys=w10 ;;
|
|
|
|
|
'windows 8.1'*) sys=w8.1 ;;
|
|
|
|
|
'windows 8'*) sys=w8 ;;
|
|
|
|
|
'windows 7'*) sys=w7 ;;
|
2023-06-18 21:27:22 +08:00
|
|
|
|
'windows vista'*) sys=2k8 ;; # virtio 没有 vista 专用驱动
|
2023-05-25 20:15:12 +08:00
|
|
|
|
esac
|
|
|
|
|
|
2023-06-04 19:05:17 +08:00
|
|
|
|
case "$sys" in
|
|
|
|
|
# https://github.com/virtio-win/virtio-win-pkg-scripts/issues/40
|
|
|
|
|
w7) dir=archive-virtio/virtio-win-0.1.173-9 ;;
|
|
|
|
|
# https://github.com/virtio-win/virtio-win-pkg-scripts/issues/61
|
|
|
|
|
2k12*) dir=archive-virtio/virtio-win-0.1.215-1 ;;
|
|
|
|
|
*) dir=stable-virtio ;;
|
|
|
|
|
esac
|
|
|
|
|
|
2023-07-03 23:11:10 +08:00
|
|
|
|
download https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/$dir/virtio-win.iso $drv/virtio-win.iso
|
|
|
|
|
mkdir -p $drv/virtio
|
|
|
|
|
mount $drv/virtio-win.iso $drv/virtio
|
2023-05-25 20:15:12 +08:00
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
# 修改应答文件
|
|
|
|
|
download $confhome/Autounattend.xml /tmp/Autounattend.xml
|
2023-05-28 00:52:48 +08:00
|
|
|
|
locale=$(wiminfo $install_wim | grep 'Default Language' | head -1 | awk '{print $NF}')
|
2023-06-05 19:54:00 +08:00
|
|
|
|
sed -i "s|%arch%|$arch|; s|%image_name%|$image_name|; s|%locale%|$locale|" /tmp/Autounattend.xml
|
2023-05-28 00:52:48 +08:00
|
|
|
|
|
|
|
|
|
# 修改应答文件,分区配置
|
|
|
|
|
line_num=$(grep -E -n '<ModifyPartitions>' /tmp/Autounattend.xml | cut -d: -f1)
|
|
|
|
|
if [ -d /sys/firmware/efi/ ]; then
|
|
|
|
|
sed -i "s|%installto_partitionid%|3|" /tmp/Autounattend.xml
|
|
|
|
|
cat <<EOF | sed -i "${line_num}r /dev/stdin" /tmp/Autounattend.xml
|
|
|
|
|
<ModifyPartition wcm:action="add">
|
|
|
|
|
<Order>1</Order>
|
|
|
|
|
<PartitionID>1</PartitionID>
|
|
|
|
|
<Format>FAT32</Format>
|
|
|
|
|
</ModifyPartition>
|
|
|
|
|
<ModifyPartition wcm:action="add">
|
|
|
|
|
<Order>2</Order>
|
|
|
|
|
<PartitionID>2</PartitionID>
|
|
|
|
|
</ModifyPartition>
|
|
|
|
|
<ModifyPartition wcm:action="add">
|
|
|
|
|
<Order>3</Order>
|
|
|
|
|
<PartitionID>3</PartitionID>
|
|
|
|
|
<Format>NTFS</Format>
|
|
|
|
|
</ModifyPartition>
|
|
|
|
|
EOF
|
|
|
|
|
else
|
|
|
|
|
sed -i "s|%installto_partitionid%|1|" /tmp/Autounattend.xml
|
|
|
|
|
cat <<EOF | sed -i "${line_num}r /dev/stdin" /tmp/Autounattend.xml
|
|
|
|
|
<ModifyPartition wcm:action="add">
|
|
|
|
|
<Order>1</Order>
|
|
|
|
|
<PartitionID>1</PartitionID>
|
|
|
|
|
<Format>NTFS</Format>
|
|
|
|
|
</ModifyPartition>
|
|
|
|
|
EOF
|
|
|
|
|
fi
|
|
|
|
|
unix2dos /tmp/Autounattend.xml
|
2023-05-25 20:15:12 +08:00
|
|
|
|
|
2023-06-04 19:09:40 +08:00
|
|
|
|
# # ei.cfg
|
|
|
|
|
# cat <<EOF >/os/installer/sources/ei.cfg
|
|
|
|
|
# [Channel]
|
|
|
|
|
# OEM
|
|
|
|
|
# EOF
|
|
|
|
|
# unix2dos /os/installer/sources/ei.cfg
|
|
|
|
|
|
2023-05-28 00:52:48 +08:00
|
|
|
|
# 挂载 boot.wim
|
2023-06-21 23:34:25 +08:00
|
|
|
|
mkdir -p /wim
|
2023-05-28 00:52:48 +08:00
|
|
|
|
wimmountrw $boot_wim 2 /wim/
|
2023-05-25 20:15:12 +08:00
|
|
|
|
|
2023-07-03 23:11:10 +08:00
|
|
|
|
cp_drivers() {
|
|
|
|
|
src=$1
|
|
|
|
|
dist=$2
|
|
|
|
|
path=$3
|
|
|
|
|
[ -n "$path" ] && filter="-ipath $path" || filter=""
|
|
|
|
|
find $src \
|
|
|
|
|
$filter \
|
2023-07-06 21:49:31 +08:00
|
|
|
|
-type f \
|
2023-07-03 23:11:10 +08:00
|
|
|
|
-not -iname "*.pdb" \
|
|
|
|
|
-not -iname "dpinst.exe" \
|
2023-07-06 21:49:31 +08:00
|
|
|
|
-exec /bin/cp -rfv {} $dist \;
|
2023-07-03 23:11:10 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# 添加驱动
|
|
|
|
|
mkdir -p /wim/drivers
|
|
|
|
|
|
|
|
|
|
[ -d $drv/virtio ] && cp_drivers $drv/virtio /wim/drivers "*/$sys/$arch/*"
|
|
|
|
|
[ -d $drv/aws ] && cp_drivers $drv/aws /wim/drivers
|
|
|
|
|
[ -d $drv/xen ] && cp_drivers $drv/xen /wim/drivers "*/$arch_xen/*"
|
2023-05-25 20:15:12 +08:00
|
|
|
|
|
|
|
|
|
# win7 要添加 bootx64.efi 到 efi 目录
|
2023-06-05 19:54:00 +08:00
|
|
|
|
[ $arch = amd64 ] && boot_efi=bootx64.efi || boot_efi=bootaa64.efi
|
2023-05-28 00:52:48 +08:00
|
|
|
|
if [ -d /sys/firmware/efi/ ] && [ ! -e /os/boot/efi/efi/boot/$boot_efi ]; then
|
2023-05-25 20:15:12 +08:00
|
|
|
|
mkdir -p /os/boot/efi/efi/boot/
|
|
|
|
|
cp /wim/Windows/Boot/EFI/bootmgfw.efi /os/boot/efi/efi/boot/$boot_efi
|
|
|
|
|
fi
|
|
|
|
|
|
2023-05-28 00:52:48 +08:00
|
|
|
|
# 复制应答文件
|
2023-05-25 20:15:12 +08:00
|
|
|
|
cp /tmp/Autounattend.xml /wim/
|
2023-05-28 00:52:48 +08:00
|
|
|
|
|
|
|
|
|
# 提交修改 boot.wim
|
|
|
|
|
wimunmount --commit /wim/
|
|
|
|
|
|
|
|
|
|
# windows 7 没有 invoke-webrequest
|
|
|
|
|
# installer分区盘符不一定是D盘
|
|
|
|
|
# 所以复制 resize.bat 到 install.wim
|
|
|
|
|
image_name=$(wiminfo $install_wim | grep -ix "Name:[[:blank:]]*$image_name" | cut -d: -f2 | xargs)
|
|
|
|
|
wimmountrw $install_wim "$image_name" /wim/
|
|
|
|
|
download $confhome/resize.bat /wim/resize.bat
|
2023-05-25 20:15:12 +08:00
|
|
|
|
wimunmount --commit /wim/
|
|
|
|
|
|
2023-05-28 00:52:48 +08:00
|
|
|
|
# 添加引导
|
|
|
|
|
if [ -d /sys/firmware/efi/ ]; then
|
|
|
|
|
apk add efibootmgr
|
|
|
|
|
efibootmgr -c -L "Windows Installer" -d /dev/$xda -p1 -l "\\EFI\\boot\\$boot_efi"
|
|
|
|
|
else
|
|
|
|
|
# 或者用 ms-sys
|
|
|
|
|
apk add grub-bios
|
|
|
|
|
grub-install --boot-directory=/os/boot /dev/$xda
|
|
|
|
|
cat <<EOF >/os/boot/grub/grub.cfg
|
|
|
|
|
set timeout=5
|
|
|
|
|
menuentry "reinstall" {
|
|
|
|
|
search --no-floppy --label --set=root installer
|
|
|
|
|
ntldr /bootmgr
|
|
|
|
|
}
|
|
|
|
|
EOF
|
|
|
|
|
fi
|
2023-07-03 13:51:59 +08:00
|
|
|
|
if [ "$sleep" = 2 ]; then
|
|
|
|
|
cd /
|
|
|
|
|
sleep infinity
|
|
|
|
|
fi
|
2023-05-25 20:15:12 +08:00
|
|
|
|
exec reboot
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
# 安装 grub2
|
2023-05-13 00:14:46 +08:00
|
|
|
|
if [ -d /sys/firmware/efi/ ]; then
|
|
|
|
|
# 注意低版本的grub无法启动f38 arm的内核
|
2023-05-04 21:45:01 +08:00
|
|
|
|
# https://forums.fedoraforum.org/showthread.php?330104-aarch64-pxeboot-vmlinuz-file-format-changed-broke-PXE-installs
|
|
|
|
|
|
2023-05-13 00:14:46 +08:00
|
|
|
|
apk add grub-efi efibootmgr
|
|
|
|
|
grub-install --efi-directory=/os/boot/efi --boot-directory=/os/boot
|
2023-05-03 22:22:21 +08:00
|
|
|
|
|
2023-05-13 00:14:46 +08:00
|
|
|
|
# 添加 netboot 备用
|
2023-07-03 23:11:10 +08:00
|
|
|
|
arch_uname=$(uname -m)
|
|
|
|
|
cd /os/boot/efi
|
|
|
|
|
if [ "$arch_uname" = aarch64 ]; then
|
2023-05-13 00:14:46 +08:00
|
|
|
|
download https://boot.netboot.xyz/ipxe/netboot.xyz-arm64.efi
|
|
|
|
|
else
|
|
|
|
|
download https://boot.netboot.xyz/ipxe/netboot.xyz.efi
|
|
|
|
|
fi
|
|
|
|
|
else
|
|
|
|
|
apk add grub-bios
|
|
|
|
|
grub-install --boot-directory=/os/boot /dev/$xda
|
2023-05-03 22:22:21 +08:00
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
# 重新整理 extra,因为grub会处理掉引号,要重新添加引号
|
|
|
|
|
for var in $(grep -o '\bextra\.[^ ]*' /proc/cmdline | xargs); do
|
2023-05-13 00:14:46 +08:00
|
|
|
|
extra_cmdline="$extra_cmdline $(echo $var | sed -E "s/(extra\.[^=]*)=(.*)/\1='\2'/")"
|
2023-05-03 22:22:21 +08:00
|
|
|
|
done
|
|
|
|
|
|
2023-05-13 00:14:46 +08:00
|
|
|
|
grub_cfg=/os/boot/grub/grub.cfg
|
2023-05-03 22:22:21 +08:00
|
|
|
|
|
2023-05-13 00:14:46 +08:00
|
|
|
|
# 新版grub不区分linux/linuxefi
|
|
|
|
|
# shellcheck disable=SC2154
|
2023-05-03 22:22:21 +08:00
|
|
|
|
if [ "$distro" = "ubuntu" ]; then
|
2023-07-03 23:11:10 +08:00
|
|
|
|
cd /os/installer/
|
2023-05-03 22:22:21 +08:00
|
|
|
|
download $iso ubuntu.iso
|
|
|
|
|
|
|
|
|
|
iso_file=/ubuntu.iso
|
|
|
|
|
# 正常写法应该是 ds="nocloud-net;s=https://xxx/" 但是甲骨文云的ds更优先,自己的ds根本无访问记录
|
|
|
|
|
# $seed 是 https://xxx/
|
|
|
|
|
cat <<EOF >$grub_cfg
|
|
|
|
|
set timeout=5
|
|
|
|
|
menuentry "reinstall" {
|
2023-05-03 23:22:59 +08:00
|
|
|
|
# https://bugs.launchpad.net/ubuntu/+source/grub2/+bug/1851311
|
2023-05-28 00:52:48 +08:00
|
|
|
|
# rmmod tpm
|
2023-05-03 22:22:21 +08:00
|
|
|
|
search --no-floppy --label --set=root installer
|
|
|
|
|
loopback loop $iso_file
|
2023-05-13 00:14:46 +08:00
|
|
|
|
linux (loop)/casper/vmlinuz iso-scan/filename=$iso_file autoinstall noprompt noeject cloud-config-url=$ks $extra_cmdline ---
|
2023-05-03 22:22:21 +08:00
|
|
|
|
initrd (loop)/casper/initrd
|
|
|
|
|
}
|
|
|
|
|
EOF
|
|
|
|
|
else
|
2023-05-13 00:14:46 +08:00
|
|
|
|
cd /os/ || exit
|
2023-05-03 22:22:21 +08:00
|
|
|
|
download $vmlinuz
|
|
|
|
|
download $initrd
|
|
|
|
|
|
2023-05-13 00:14:46 +08:00
|
|
|
|
cd /os/installer/ || exit
|
2023-05-03 22:22:21 +08:00
|
|
|
|
download $squashfs install.img
|
|
|
|
|
|
|
|
|
|
cat <<EOF >$grub_cfg
|
|
|
|
|
set timeout=5
|
|
|
|
|
menuentry "reinstall" {
|
|
|
|
|
search --no-floppy --label --set=root os
|
2023-05-13 00:14:46 +08:00
|
|
|
|
linux /vmlinuz inst.stage2=hd:LABEL=installer:/install.img inst.ks=$ks $extra_cmdline
|
|
|
|
|
initrd /initrd.img
|
2023-05-03 22:22:21 +08:00
|
|
|
|
}
|
|
|
|
|
EOF
|
|
|
|
|
fi
|
|
|
|
|
reboot
|