core: 重构代码

This commit is contained in:
bin456789 2023-07-25 00:21:08 +08:00
parent e6654dab05
commit ba456c65eb
No known key found for this signature in database
GPG Key ID: EE301B386DE6C11B

388
trans.sh
View File

@ -20,6 +20,11 @@ error() {
wall "Error: $*" wall "Error: $*"
} }
error_and_exit() {
error "$@"
exit 1
}
add_community_repo() { add_community_repo() {
if ! grep -x 'http.*/community' /etc/apk/repositories; then if ! grep -x 'http.*/community' /etc/apk/repositories; then
alpine_ver=$(cut -d. -f1,2 </etc/alpine-release) alpine_ver=$(cut -d. -f1,2 </etc/alpine-release)
@ -106,6 +111,16 @@ EOF
fi fi
} }
setup_nginx_if_enough_ram() {
total_ram=$(free -m | awk '{print $2}' | sed -n '2p')
# 避免后面没内存安装程序谨慎起见512内存才安装
if [ $total_ram -gt 400 ]; then
# lighttpd 虽然运行占用内存少,但安装占用空间大
# setup_lighttpd
setup_nginx
fi
}
setup_lighttpd() { setup_lighttpd() {
apk add lighttpd apk add lighttpd
ln -sf /reinstall.html /var/www/localhost/htdocs/index.html ln -sf /reinstall.html /var/www/localhost/htdocs/index.html
@ -164,42 +179,7 @@ clear_previous() {
} 2>/dev/null || true } 2>/dev/null || true
} }
clear_previous install_alpine() {
setup_tty_and_log
extract_env_from_cmdline
# 安装 nginx目标系统是 alpine 除外
# shellcheck disable=SC2154
if [ "$distro" != "alpine" ]; then
total_ram=$(free -m | awk '{print $2}' | sed -n '2p')
# 避免后面没内存安装程序谨慎起见512内存才安装
if [ $total_ram -gt 400 ]; then
# lighttpd 虽然运行占用内存少,但安装占用空间大
# setup_lighttpd
setup_nginx
fi
fi
# 找到主硬盘
# alpine 不自带lsblkliveos安装的软件也会被带到新系统所以不用lsblk
# xda=$(lsblk -dn -o NAME | grep -E 'nvme0n1|.da')
# shellcheck disable=SC2010
xda=$(ls /dev/ | grep -Ex 'sda|hda|xda|vda|xvda|nvme0n1')
# arm要手动从硬件同步时间避免访问https出错
hwclock -s
# 安装并打开 ssh
echo root:123@@@ | chpasswd
printf '\nyes' | setup-sshd
# shellcheck disable=SC2154
if [ "$sleep" = 1 ]; then
exit
fi
# shellcheck disable=SC2154
if [ "$distro" = "alpine" ]; then
# 还原改动,不然本脚本会被复制到新系统 # 还原改动,不然本脚本会被复制到新系统
rm -f /etc/local.d/trans.start rm -f /etc/local.d/trans.start
rm -f /etc/runlevels/default/local rm -f /etc/runlevels/default/local
@ -247,9 +227,10 @@ if [ "$distro" = "alpine" ]; then
# alpine默认使用 syslinux (efi 环境除外),这里强制使用 grub方便用脚本再次重装 # alpine默认使用 syslinux (efi 环境除外),这里强制使用 grub方便用脚本再次重装
export BOOTLOADER="grub" export BOOTLOADER="grub"
printf 'y' | setup-disk -m sys $kernel_opt -s 0 /dev/$xda printf 'y' | setup-disk -m sys $kernel_opt -s 0 /dev/$xda
exec reboot }
elif [ "$distro" = "dd" ]; then # shellcheck disable=SC2154
install_dd() {
case "$img_type" in case "$img_type" in
gzip) prog=gzip ;; gzip) prog=gzip ;;
xz) prog=xz ;; xz) prog=xz ;;
@ -263,122 +244,117 @@ elif [ "$distro" = "dd" ]; then
curl -L $img | $prog -dc >/dev/$xda curl -L $img | $prog -dc >/dev/$xda
sync sync
else else
echo 'Not supported' error_and_exit 'Not supported'
sleep 1m
fi fi
if [ "$sleep" = 2 ]; then }
exit
fi
exec reboot
fi
# 目标系统非 alpine 和 dd is_xda_gt_2t() {
# 脚本开始 disk_size=$(blockdev --getsize64 /dev/$xda)
add_community_repo disk_2t=$((2 * 1024 * 1024 * 1024 * 1024))
if ! apk add util-linux aria2 grub udev hdparm e2fsprogs curl parted; then [ "$disk_size" -gt "$disk_2t" ]
echo 'Unable to install package!' }
sleep 1m
exec reboot
fi
# 打开dev才能刷新分区名 create_part() {
rc-service udev start # 目标系统非 alpine 和 dd
# 脚本开始
apk add util-linux aria2 grub udev hdparm e2fsprogs curl parted
# 反激活 lvm # 打开dev才能刷新分区名
# alpine live 不需要 rc-service udev start
false && vgchange -an
# 移除 lsblk 显示的分区 # 反激活 lvm
partx -d /dev/$xda # alpine live 不需要
false && vgchange -an
disk_size=$(blockdev --getsize64 /dev/$xda) # 移除 lsblk 显示的分区
disk_2t=$((2 * 1024 * 1024 * 1024 * 1024)) partx -d /dev/$xda
# xda*1 星号用于 nvme0n1p1 的字母 p # xda*1 星号用于 nvme0n1p1 的字母 p
if [ "$distro" = windows ]; then if [ "$distro" = windows ]; then
apk add ntfs-3g-progs virt-what wimlib rsync dos2unix apk add ntfs-3g-progs virt-what wimlib rsync dos2unix
# 虽然ntfs3不需要fuse但wimmount需要所以还是要保留 # 虽然ntfs3不需要fuse但wimmount需要所以还是要保留
modprobe fuse ntfs3 modprobe fuse ntfs3
if is_efi; then if is_efi; then
# efi # efi
apk add dosfstools apk add dosfstools
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
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
else
# 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
fi
elif is_use_cloud_image; then
parted /dev/$xda -s -- \ parted /dev/$xda -s -- \
mklabel gpt \ mklabel gpt \
mkpart '" "' fat32 1MiB 1025MiB \ mkpart '" "' ext4 1MiB -2GiB \
mkpart '" "' fat32 1025MiB 1041MiB \ mkpart '" "' ext4 -2GiB 100%
mkpart '" "' ext4 1041MiB -6GiB \
mkpart '" "' ntfs -6GiB 100% \
set 1 boot on \
set 2 msftres on \
set 3 msftdata on
update_part /dev/$xda
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
else
# 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
fi
elif is_use_cloud_image; then
parted /dev/$xda -s -- \
mklabel gpt \
mkpart '" "' ext4 1MiB -2GiB \
mkpart '" "' ext4 -2GiB 100%
update_part /dev/$xda
mkfs.ext4 -F -L os /dev/$xda*1 #1 os
mkfs.ext4 -F -L installer /dev/$xda*2 #2 installer
else
# 对于红帽系是临时分区表,安装时除了 installer 分区,其他分区会重建为默认的大小
# 对于ubuntu是最终分区表因为 ubuntu 的安装器不能调整个别分区,只能重建整个分区表
if is_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
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
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 -F -L os /dev/$xda*2 #2 os
mkfs.ext4 -F -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 update_part /dev/$xda
mkfs.ext4 -F -L os /dev/$xda*1 #1 os mkfs.ext4 -F -L os /dev/$xda*1 #1 os
mkfs.ext4 -F -L installer /dev/$xda*2 #2 installer mkfs.ext4 -F -L installer /dev/$xda*2 #2 installer
else
# 对于红帽系是临时分区表,安装时除了 installer 分区,其他分区会重建为默认的大小
# 对于ubuntu是最终分区表因为 ubuntu 的安装器不能调整个别分区,只能重建整个分区表
if is_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
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
elif is_xda_gt_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 -F -L os /dev/$xda*2 #2 os
mkfs.ext4 -F -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 -F -L os /dev/$xda*1 #1 os
mkfs.ext4 -F -L installer /dev/$xda*2 #2 installer
fi
fi fi
fi
update_part /dev/$xda update_part /dev/$xda
}
if is_use_cloud_image; then install_cloud_image() {
apk add qemu-img lsblk apk add qemu-img lsblk
mkdir -p /installer mkdir -p /installer
@ -434,8 +410,9 @@ if is_use_cloud_image; then
fi fi
# shellcheck disable=SC2154 # shellcheck disable=SC2154
download $confhome/nocloud.yaml /os$subvol/etc/cloud/cloud.cfg.d/99_nocloud.cfg download $confhome/nocloud.yaml /os$subvol/etc/cloud/cloud.cfg.d/99_nocloud.cfg
exit }
else
mount_part() {
# 挂载主分区 # 挂载主分区
mkdir -p /os mkdir -p /os
mount /dev/disk/by-label/os /os mount /dev/disk/by-label/os /os
@ -450,10 +427,10 @@ else
mount_args="-t ntfs3" mount_args="-t ntfs3"
fi fi
mount $mount_args /dev/disk/by-label/installer /os/installer mount $mount_args /dev/disk/by-label/installer /os/installer
fi }
# shellcheck disable=SC2154 install_windows() {
if [ "$distro" = "windows" ]; then # shellcheck disable=SC2154
download $iso /os/windows.iso download $iso /os/windows.iso
mkdir -p /iso mkdir -p /iso
mount /os/windows.iso /iso mount /os/windows.iso /iso
@ -723,49 +700,45 @@ EOF
} }
EOF EOF
fi fi
if [ "$sleep" = 2 ]; then }
cd /
sleep infinity
fi
exec reboot
fi
# 安装 grub2 install_redhat_ubuntu() {
if is_efi; then # 安装 grub2
# 注意低版本的grub无法启动f38 arm的内核 if is_efi; then
# https://forums.fedoraforum.org/showthread.php?330104-aarch64-pxeboot-vmlinuz-file-format-changed-broke-PXE-installs # 注意低版本的grub无法启动f38 arm的内核
# https://forums.fedoraforum.org/showthread.php?330104-aarch64-pxeboot-vmlinuz-file-format-changed-broke-PXE-installs
apk add grub-efi efibootmgr apk add grub-efi efibootmgr
grub-install --efi-directory=/os/boot/efi --boot-directory=/os/boot grub-install --efi-directory=/os/boot/efi --boot-directory=/os/boot
# 添加 netboot 备用 # 添加 netboot 备用
arch_uname=$(uname -m) arch_uname=$(uname -m)
cd /os/boot/efi cd /os/boot/efi
if [ "$arch_uname" = aarch64 ]; then if [ "$arch_uname" = aarch64 ]; then
download https://boot.netboot.xyz/ipxe/netboot.xyz-arm64.efi download https://boot.netboot.xyz/ipxe/netboot.xyz-arm64.efi
else
download https://boot.netboot.xyz/ipxe/netboot.xyz.efi
fi
else else
download https://boot.netboot.xyz/ipxe/netboot.xyz.efi apk add grub-bios
grub-install --boot-directory=/os/boot /dev/$xda
fi fi
else
apk add grub-bios
grub-install --boot-directory=/os/boot /dev/$xda
fi
# 重新整理 extra因为grub会处理掉引号要重新添加引号 # 重新整理 extra因为grub会处理掉引号要重新添加引号
for var in $(grep -o '\bextra\.[^ ]*' /proc/cmdline | xargs); do for var in $(grep -o '\bextra\.[^ ]*' /proc/cmdline | xargs); do
extra_cmdline="$extra_cmdline $(echo $var | sed -E "s/(extra\.[^=]*)=(.*)/\1='\2'/")" extra_cmdline="$extra_cmdline $(echo $var | sed -E "s/(extra\.[^=]*)=(.*)/\1='\2'/")"
done done
grub_cfg=/os/boot/grub/grub.cfg grub_cfg=/os/boot/grub/grub.cfg
# 新版grub不区分linux/linuxefi # 新版grub不区分linux/linuxefi
# shellcheck disable=SC2154 # shellcheck disable=SC2154
if [ "$distro" = "ubuntu" ]; then if [ "$distro" = "ubuntu" ]; then
download $iso /os/installer/ubuntu.iso download $iso /os/installer/ubuntu.iso
# 正常写法应该是 ds="nocloud-net;s=https://xxx/" 但是甲骨文云的ds更优先自己的ds根本无访问记录 # 正常写法应该是 ds="nocloud-net;s=https://xxx/" 但是甲骨文云的ds更优先自己的ds根本无访问记录
# $seed 是 https://xxx/ # $seed 是 https://xxx/
cat <<EOF >$grub_cfg cat <<EOF >$grub_cfg
set timeout=5 set timeout=5
menuentry "reinstall" { menuentry "reinstall" {
# https://bugs.launchpad.net/ubuntu/+source/grub2/+bug/1851311 # https://bugs.launchpad.net/ubuntu/+source/grub2/+bug/1851311
@ -776,12 +749,12 @@ if [ "$distro" = "ubuntu" ]; then
initrd (loop)/casper/initrd initrd (loop)/casper/initrd
} }
EOF EOF
else else
download $vmlinuz /os/vmlinuz download $vmlinuz /os/vmlinuz
download $initrd /os/initrd.img download $initrd /os/initrd.img
download $squashfs /os/installer/install.img download $squashfs /os/installer/install.img
cat <<EOF >$grub_cfg cat <<EOF >$grub_cfg
set timeout=5 set timeout=5
menuentry "reinstall" { menuentry "reinstall" {
search --no-floppy --label --set=root os search --no-floppy --label --set=root os
@ -789,5 +762,54 @@ else
initrd /initrd.img initrd /initrd.img
} }
EOF EOF
fi
}
# 脚本入口
# arm要手动从硬件同步时间避免访问https出错
hwclock -s
# 设置密码,安装并打开 ssh
echo root:123@@@ | chpasswd
printf '\nyes' | setup-sshd
extract_env_from_cmdline
# shellcheck disable=SC2154
if [ "$sleep" = 1 ]; then
exit
fi
setup_tty_and_log
clear_previous
# 找到主硬盘
# shellcheck disable=SC2010
xda=$(ls /dev/ | grep -Ex 'sda|hda|xda|vda|xvda|nvme0n1')
# shellcheck disable=SC2154
if [ "$distro" != "alpine" ]; then
setup_nginx_if_enough_ram
add_community_repo
fi
if [ "$distro" = "alpine" ]; then
install_alpine
elif [ "$distro" = "dd" ]; then
install_dd
elif is_use_cloud_image; then
create_part
install_cloud_image
else
create_part
mount_part
if [ "$distro" = "windows" ]; then
install_windows
else
install_redhat_ubuntu
fi
fi
if [ "$sleep" = 2 ]; then
exit
fi fi
reboot reboot