mirror of
https://github.com/bin456789/reinstall.git
synced 2026-02-04 17:14:17 +08:00
Compare commits
9 Commits
main
...
0592789fbf
| Author | SHA1 | Date | |
|---|---|---|---|
| 0592789fbf | |||
| 2d970ac458 | |||
| cb9e413aa4 | |||
| acb069b696 | |||
| ef78438f9e | |||
| 944282079c | |||
| 889f0de3b6 | |||
| f7104cc6af | |||
| 798539d272 |
25
README.en.md
25
README.en.md
@ -4,8 +4,7 @@
|
||||
|
||||
[](https://app.codacy.com/gh/bin456789/reinstall/dashboard)
|
||||
[](https://www.codefactor.io/repository/github/bin456789/reinstall)
|
||||
[](https://github.com/aschey/vercel-tokei)
|
||||
<!-- [](https://github.com/XAMPPRocky/tokei_rs) -->
|
||||
[](https://github.com/XAMPPRocky/tokei_rs)
|
||||
|
||||
One-Click system reinstallation script for VPS [中文](README.md)
|
||||
|
||||
@ -35,7 +34,7 @@ If this helped you, you can buy me a milk tea.
|
||||
- [Download](#download-current-system-is--linux)
|
||||
- [Feature 1. One-click reinstallation to Linux](#feature-1-install--linux)
|
||||
- [Feature 2. One-click DD Raw image to hard disk](#feature-2-dd-raw-image-to-hard-disk)
|
||||
- [Feature 3. One-click reboot to Alpine Live OS](#feature-3-reboot-to--alpine-live-os)
|
||||
- [Feature 3. One-click reboot to Alpine Live OS in-memory system](#feature-3-reboot-to--alpine-live-os-ram-os)
|
||||
- [Feature 4. One-click reboot to netboot.xyz](#feature-4-reboot-to--netbootxyz)
|
||||
- [Feature 5. One-click reinstallation to Windows](#feature-5-install--windows-iso)
|
||||
|
||||
@ -47,7 +46,7 @@ The system requirements for the target system are as follows:
|
||||
|
||||
| System | Version | Memory | Disk |
|
||||
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------- | --------- | ---------------- |
|
||||
| <img width="16" height="16" src="https://www.alpinelinux.org/alpine-logo.ico" /> Alpine | 3.20, 3.21, 3.22, 3.23 | 256 MB | 1 GB |
|
||||
| <img width="16" height="16" src="https://www.alpinelinux.org/alpine-logo.ico" /> Alpine | 3.19, 3.20, 3.21, 3.22 | 256 MB | 1 GB |
|
||||
| <img width="16" height="16" src="https://www.debian.org/favicon.ico" /> Debian | 9, 10, 11, 12, 13 | 256 MB | 1 ~ 1.5 GB ^ |
|
||||
| <img width="16" height="16" src="https://github.com/bin456789/reinstall/assets/7548515/f74b3d5b-085f-4df3-bcc9-8a9bd80bb16d" /> Kali | Rolling | 256 MB | 1 ~ 1.5 GB ^ |
|
||||
| <img width="16" height="16" src="https://documentation.ubuntu.com/server/_static/favicon.png" /> Ubuntu | 16.04 LTS - 24.04 LTS, 25.10 | 512 MB \* | 2 GB |
|
||||
@ -58,11 +57,11 @@ The system requirements for the target system are as follows:
|
||||
| <img width="16" height="16" src="https://fedoraproject.org/favicon.ico" /> Fedora | 42, 43 | 512 MB \* | 5 GB |
|
||||
| <img width="16" height="16" src="https://www.openeuler.org/favicon.ico" /> openEuler | 20.03 LTS - 24.03 LTS, 25.09 | 512 MB \* | 5 GB |
|
||||
| <img width="16" height="16" src="https://static.opensuse.org/favicon.ico" /> openSUSE | Leap 15.6, 16.0, Tumbleweed (Rolling) | 512 MB \* | 5 GB |
|
||||
| <img width="16" height="16" src="https://nixos.org/favicon.svg" /> NixOS | 25.11 | 512 MB | 5 GB |
|
||||
| <img width="16" height="16" src="https://nixos.org/favicon.svg" /> NixOS | 25.05 | 512 MB | 5 GB |
|
||||
| <img width="16" height="16" src="https://archlinux.org/static/favicon.png" /> Arch | Rolling | 512 MB | 5 GB |
|
||||
| <img width="16" height="16" src="https://www.gentoo.org/assets/img/logo/gentoo-g.png" /> Gentoo | Rolling | 512 MB | 5 GB |
|
||||
| <img width="16" height="16" src="https://aosc.io/distros/aosc-os.svg" /> AOSC OS | Rolling | 512 MB | 5 GB |
|
||||
| <img width="16" height="16" src="https://www.fnnas.com/favicon.ico" /> fnOS | 1 | 512 MB | 8 GB |
|
||||
| <img width="16" height="16" src="https://www.fnnas.com/favicon.ico" /> fnOS | Beta | 512 MB | 8 GB |
|
||||
| <img width="16" height="16" src="https://blogs.windows.com/wp-content/uploads/prod/2022/09/cropped-Windows11IconTransparent512-32x32.png" /> Windows (DD) | Any | 512 MB | Depends on image |
|
||||
| <img width="16" height="16" src="https://blogs.windows.com/wp-content/uploads/prod/2022/09/cropped-Windows11IconTransparent512-32x32.png" /> Windows (ISO) | Vista, 7, 8.x (Server 2008 - 2012 R2) | 512 MB | 25 GB |
|
||||
| <img width="16" height="16" src="https://blogs.windows.com/wp-content/uploads/prod/2022/09/cropped-Windows11IconTransparent512-32x32.png" /> Windows (ISO) | 10, 11 (Server 2016 - 2025) | 1 GB | 25 GB |
|
||||
@ -150,7 +149,7 @@ certutil -urlcache -f -split https://cnb.cool/bin456789/reinstall/-/git/raw/main
|
||||
- When installing the latest version, the version number does not need to be specified.
|
||||
- Maximizes disk space usage: no boot partition (except for Fedora) and no swap partition.
|
||||
- Automatically selects different optimized kernels based on machine type, such as `Cloud` or `HWE` kernels.
|
||||
- When installing Red Hat, you must provide the `qcow2` image link obtained from <https://access.redhat.com/downloads/content/rhel>. You can also install `qcow2` of other RHEL-based OS, such as `Alibaba Cloud Linux` and `TencentOS Server`.
|
||||
- When installing Red Hat, you must provide the `qcow2` image link obtained from <https://access.redhat.com/downloads/content/rhel>. You can also install other RHEL-based OS, such as `Alibaba Cloud Linux` and `TencentOS Server`.
|
||||
- After reinstallation, if you need to change the SSH port or switch to key-based login, make sure to also modify the files inside `/etc/ssh/sshd_config.d/`.
|
||||
|
||||
```bash
|
||||
@ -160,11 +159,10 @@ bash reinstall.sh anolis 7|8|23
|
||||
almalinux 8|9|10
|
||||
opencloudos 8|9|23
|
||||
centos 9|10
|
||||
fnos 1
|
||||
nixos 25.11
|
||||
fedora 42|43
|
||||
nixos 25.05
|
||||
debian 9|10|11|12|13
|
||||
alpine 3.20|3.21|3.22|3.23
|
||||
alpine 3.19|3.20|3.21|3.22
|
||||
opensuse 15.6|16.0|tumbleweed
|
||||
openeuler 20.03|22.03|24.03|25.09
|
||||
ubuntu 16.04|18.04|20.04|22.04|24.04|25.10 [--minimal]
|
||||
@ -172,6 +170,7 @@ bash reinstall.sh anolis 7|8|23
|
||||
arch
|
||||
gentoo
|
||||
aosc
|
||||
fnos
|
||||
redhat --img="http://access.cdn.redhat.com/xxx.qcow2"
|
||||
```
|
||||
|
||||
@ -259,7 +258,7 @@ bash reinstall.sh dd --img "https://example.com/xxx.xz"
|
||||
>
|
||||
> Or Run `/trans.sh alpine` to automatically recover to Alpine Linux.
|
||||
|
||||
### Feature 3: Reboot to <img width="16" height="16" src="https://www.alpinelinux.org/alpine-logo.ico" /> Alpine Live OS
|
||||
### Feature 3: Reboot to <img width="16" height="16" src="https://www.alpinelinux.org/alpine-logo.ico" /> Alpine Live OS (RAM OS)
|
||||
|
||||
- You can use SSH to backup/restore disk, manually perform DD operations, partition modifications, manual Alpine installation, and other operations.
|
||||
- Username `root`. The script prompts for a password. If left blank, a random one is generated.
|
||||
@ -267,7 +266,7 @@ bash reinstall.sh dd --img "https://example.com/xxx.xz"
|
||||
> [!TIP]
|
||||
>
|
||||
> Although the script being run is `reinstall`, this feature **does not** delete any data or perform an automatic reinstallation; manual user operation is required.
|
||||
>
|
||||
|
||||
> If the user does not damage the original system during manual operation, rebooting will return to the original system.
|
||||
|
||||
```bash
|
||||
@ -288,7 +287,7 @@ bash reinstall.sh alpine --hold 1
|
||||
> [!TIP]
|
||||
>
|
||||
> Although the script being run is `reinstall`, this feature **does not** delete any data or perform an automatic reinstallation; manual user operation is required.
|
||||
>
|
||||
|
||||
> If the user does not damage the original system during manual operation, rebooting will return to the original system.
|
||||
|
||||
```bash
|
||||
|
||||
17
README.md
17
README.md
@ -4,8 +4,7 @@
|
||||
|
||||
[](https://app.codacy.com/gh/bin456789/reinstall/dashboard)
|
||||
[](https://www.codefactor.io/repository/github/bin456789/reinstall)
|
||||
[](https://github.com/aschey/vercel-tokei)
|
||||
<!-- [](https://github.com/XAMPPRocky/tokei_rs) -->
|
||||
[](https://github.com/XAMPPRocky/tokei_rs)
|
||||
|
||||
一键 VPS 系统重装脚本 [English](README.en.md)
|
||||
|
||||
@ -47,7 +46,7 @@
|
||||
|
||||
| 系统 | 版本 | 内存 | 硬盘 |
|
||||
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------- | --------- | ------------ |
|
||||
| <img width="16" height="16" src="https://www.alpinelinux.org/alpine-logo.ico" /> Alpine | 3.20, 3.21, 3.22, 3.23 | 256 MB | 1 GB |
|
||||
| <img width="16" height="16" src="https://www.alpinelinux.org/alpine-logo.ico" /> Alpine | 3.19, 3.20, 3.21, 3.22 | 256 MB | 1 GB |
|
||||
| <img width="16" height="16" src="https://www.debian.org/favicon.ico" /> Debian | 9, 10, 11, 12, 13 | 256 MB | 1 ~ 1.5 GB ^ |
|
||||
| <img width="16" height="16" src="https://github.com/bin456789/reinstall/assets/7548515/f74b3d5b-085f-4df3-bcc9-8a9bd80bb16d" /> Kali | 滚动 | 256 MB | 1 ~ 1.5 GB ^ |
|
||||
| <img width="16" height="16" src="https://documentation.ubuntu.com/server/_static/favicon.png" /> Ubuntu | 16.04 LTS - 24.04 LTS, 25.10 | 512 MB \* | 2 GB |
|
||||
@ -58,11 +57,11 @@
|
||||
| <img width="16" height="16" src="https://fedoraproject.org/favicon.ico" /> Fedora | 42, 43 | 512 MB \* | 5 GB |
|
||||
| <img width="16" height="16" src="https://www.openeuler.org/favicon.ico" /> openEuler | 20.03 LTS - 24.03 LTS, 25.09 | 512 MB \* | 5 GB |
|
||||
| <img width="16" height="16" src="https://static.opensuse.org/favicon.ico" /> openSUSE | Leap 15.6, 16.0, Tumbleweed (滚动) | 512 MB \* | 5 GB |
|
||||
| <img width="16" height="16" src="https://nixos.org/favicon.svg" /> NixOS | 25.11 | 512 MB | 5 GB |
|
||||
| <img width="16" height="16" src="https://nixos.org/favicon.svg" /> NixOS | 25.05 | 512 MB | 5 GB |
|
||||
| <img width="16" height="16" src="https://archlinux.org/static/favicon.png" /> Arch | 滚动 | 512 MB | 5 GB |
|
||||
| <img width="16" height="16" src="https://www.gentoo.org/assets/img/logo/gentoo-g.png" /> Gentoo | 滚动 | 512 MB | 5 GB |
|
||||
| <img width="16" height="16" src="https://aosc.io/distros/aosc-os.svg" /> 安同 OS | 滚动 | 512 MB | 5 GB |
|
||||
| <img width="16" height="16" src="https://www.fnnas.com/favicon.ico" /> 飞牛 fnOS | 1 | 512 MB | 8 GB |
|
||||
| <img width="16" height="16" src="https://www.fnnas.com/favicon.ico" /> 飞牛 fnOS | 公测 | 512 MB | 8 GB |
|
||||
| <img width="16" height="16" src="https://blogs.windows.com/wp-content/uploads/prod/2022/09/cropped-Windows11IconTransparent512-32x32.png" /> Windows (DD) | 任何 | 512 MB | 取决于镜像 |
|
||||
| <img width="16" height="16" src="https://blogs.windows.com/wp-content/uploads/prod/2022/09/cropped-Windows11IconTransparent512-32x32.png" /> Windows (ISO) | Vista, 7, 8.x (Server 2008 - 2012 R2) | 512 MB | 25 GB |
|
||||
| <img width="16" height="16" src="https://blogs.windows.com/wp-content/uploads/prod/2022/09/cropped-Windows11IconTransparent512-32x32.png" /> Windows (ISO) | 10, 11 (Server 2016 - 2025) | 1 GB | 25 GB |
|
||||
@ -150,7 +149,7 @@ certutil -urlcache -f -split https://cnb.cool/bin456789/reinstall/-/git/raw/main
|
||||
- 安装最新版可不输入版本号
|
||||
- 最大化利用磁盘空间:不含 boot 分区(Fedora 例外),不含 swap 分区
|
||||
- 自动根据机器类型选择不同的优化内核,例如 `Cloud`、`HWE` 内核
|
||||
- 安装 Red Hat 时需填写 <https://access.redhat.com/downloads/content/rhel> 得到的 `qcow2` 镜像链接,也可以安装其它类 RHEL 系统的 `qcow2`,例如 `Alibaba Cloud Linux` 和 `TencentOS Server`
|
||||
- 安装 Red Hat 时需填写 <https://access.redhat.com/downloads/content/rhel> 得到的 `qcow2` 镜像链接,也可以安装其它类 RHEL 系统,例如 `Alibaba Cloud Linux` 和 `TencentOS Server`
|
||||
- 重装后如需修改 SSH 端口或者改成密钥登录,注意还要修改 `/etc/ssh/sshd_config.d/` 里面的文件
|
||||
|
||||
```bash
|
||||
@ -160,11 +159,10 @@ bash reinstall.sh anolis 7|8|23
|
||||
almalinux 8|9|10
|
||||
opencloudos 8|9|23
|
||||
centos 9|10
|
||||
fnos 1
|
||||
nixos 25.11
|
||||
fedora 42|43
|
||||
nixos 25.05
|
||||
debian 9|10|11|12|13
|
||||
alpine 3.20|3.21|3.22|3.23
|
||||
alpine 3.19|3.20|3.21|3.22
|
||||
opensuse 15.6|16.0|tumbleweed
|
||||
openeuler 20.03|22.03|24.03|25.09
|
||||
ubuntu 16.04|18.04|20.04|22.04|24.04|25.10 [--minimal]
|
||||
@ -172,6 +170,7 @@ bash reinstall.sh anolis 7|8|23
|
||||
arch
|
||||
gentoo
|
||||
aosc
|
||||
fnos
|
||||
redhat --img="http://access.cdn.redhat.com/xxx.qcow2"
|
||||
```
|
||||
|
||||
|
||||
@ -48,40 +48,21 @@ retry() {
|
||||
# 用 systemd-analyze plot >a.svg 发现 sys-subsystem-net-devices-enp3s0.device 也是出现在 NetworkManager 之后
|
||||
# 因此需要等待网卡出现
|
||||
get_ethx_by_mac() {
|
||||
retry 10 _get_ethx_by_mac "$@"
|
||||
mac=$(echo "$1" | to_lower)
|
||||
retry 10 _get_ethx_by_mac "$mac"
|
||||
}
|
||||
|
||||
_get_ethx_by_mac() {
|
||||
mac=$(echo "$1" | to_lower)
|
||||
|
||||
flag=$2
|
||||
if [ -z "$flag" ]; then
|
||||
flag=master
|
||||
fi
|
||||
|
||||
if true; then
|
||||
if [ "$flag" = master ]; then
|
||||
# master
|
||||
# 过滤 azure vf (带 master ethx)
|
||||
ip -o link | grep -i "$mac" | grep -v master | awk '{print $2}' | cut -d: -f1 | grep .
|
||||
else
|
||||
# slave
|
||||
# 带 master ethx
|
||||
ip -o link | grep -i "$mac" | grep -w master | awk '{print $2}' | cut -d: -f1 | grep .
|
||||
fi
|
||||
return
|
||||
else
|
||||
for i in $(cd /sys/class/net && echo *); do
|
||||
if [ "$(cat "/sys/class/net/$i/address")" = "$mac" ]; then
|
||||
if [ $(($(cat "/sys/class/net/$i/flags") & 0x800)) -ne 0 ]; then
|
||||
fact_flag=slave
|
||||
else
|
||||
fact_flag=master
|
||||
fi
|
||||
if [ "$flag" = "$fact_flag" ]; then
|
||||
echo "$i"
|
||||
return
|
||||
fi
|
||||
fi
|
||||
done
|
||||
return 1
|
||||
fi
|
||||
@ -157,23 +138,6 @@ fix_network_manager() {
|
||||
|
||||
# 更改文件名
|
||||
mv "$file" "$proper_file"
|
||||
|
||||
# NM 不会自动忽略 Azure 的 slave 网卡,需手动设置
|
||||
# azure 文档中的方法不够通用,只适合 azure
|
||||
# https://learn.microsoft.com/zh-cn/azure/virtual-network/accelerated-networking-overview
|
||||
|
||||
# 我们采用红帽的方法
|
||||
# https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/8/html/configuring_and_managing_networking/configuring-networkmanager-to-ignore-certain-devices_configuring-and-managing-networking
|
||||
if slave_ethx=$(get_ethx_by_mac "$mac" slave); then
|
||||
cat >"/etc/NetworkManager/conf.d/99-$slave_ethx-unmanaged.conf" <<EOF
|
||||
[device-$slave_ethx-unmanaged]
|
||||
match-device=interface-name:$slave_ethx
|
||||
managed=0
|
||||
EOF
|
||||
fi
|
||||
|
||||
# 也可以设置 unmanaged-devices, 但是官方文档不推荐
|
||||
# https://networkmanager.pages.freedesktop.org/NetworkManager/NetworkManager/NetworkManager.conf.html#:~:text=may%20be%20a-,better%20choice,-.
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
@ -60,7 +60,6 @@ get_frpc_url() {
|
||||
mirror=$(
|
||||
# nju 没有 win7 用的旧版
|
||||
# github 不支持 ipv6
|
||||
# daocloud 加速不支持 ipv6
|
||||
# jsdelivr 不支持 github releases 文件
|
||||
if is_ipv6_only; then
|
||||
if is_need_old_version; then
|
||||
@ -72,7 +71,7 @@ get_frpc_url() {
|
||||
else
|
||||
if is_in_china; then
|
||||
if is_need_old_version; then
|
||||
echo https://files.m.daocloud.io/github.com/fatedier/frp/releases/download
|
||||
echo https://github.com/fatedier/frp/releases/download
|
||||
else
|
||||
echo https://mirrors.nju.edu.cn/github-release/fatedier/frp
|
||||
fi
|
||||
|
||||
@ -345,14 +345,14 @@ EOF
|
||||
db_progress INFO netcfg/link_detect_progress
|
||||
else
|
||||
# alpine
|
||||
# h3c 移动云电脑使用 udhcpc 会重复提示 sending select,因此添加 timeout 强制结束进程
|
||||
# h3c 移动云电脑使用 udhcpc 会重复提示 sending select,无法获得 ipv6
|
||||
# dhcpcd 会配置租约时间,过期会移除 IP,但我们的没有在后台运行 dhcpcd ,因此用 udhcpc
|
||||
method=udhcpc
|
||||
|
||||
case "$method" in
|
||||
udhcpc)
|
||||
timeout $DHCP_TIMEOUT udhcpc -i "$ethx" -f -q -n || true
|
||||
timeout $DHCP_TIMEOUT udhcpc6 -i "$ethx" -f -q -n || true
|
||||
udhcpc -i "$ethx" -f -q -n || true
|
||||
udhcpc6 -i "$ethx" -f -q -n || true
|
||||
sleep $DNS_FILE_TIMEOUT # 好像不用等待写入 dns,但是以防万一
|
||||
;;
|
||||
dhcpcd)
|
||||
|
||||
@ -131,13 +131,6 @@ call :check_cygwin_installed || (
|
||||
set dir=/sourceware/cygwin
|
||||
)
|
||||
|
||||
rem daocloud 加速有 90 天缓存,且不支持 IPv6
|
||||
rem https://github.com/DaoCloud/public-binary-files-mirror
|
||||
rem 无法用查询字符串强制刷新缓存
|
||||
rem https://files.m.daocloud.io/www.cloudflare.com/cdn-cgi/trace?a=1
|
||||
rem https://files.m.daocloud.io/www.cloudflare.com/cdn-cgi/trace?b=2
|
||||
rem 也就无法用 https://www.cygwin.com/setup-x86_64.exe?xxx=20250101 强制每天刷新缓存
|
||||
|
||||
rem 下载 Cygwin
|
||||
if not exist setup-!CygwinArch!.exe (
|
||||
call :download http://www.cygwin.com/setup-!CygwinArch!.exe %~dp0setup-!CygwinArch!.exe || goto :download_failed
|
||||
@ -202,7 +195,7 @@ rem bitsadmin /transfer "%~3" /priority foreground %~1 %~2
|
||||
:download
|
||||
rem certutil 会被 windows Defender 报毒
|
||||
rem windows server 2019 要用第二条 certutil 命令
|
||||
echo Downloading: %~1 %~2
|
||||
echo Download: %~1 %~2
|
||||
del /q "%~2" 2>nul
|
||||
if exist "%~2" (echo Cannot delete %~2 & exit /b 1)
|
||||
|
||||
|
||||
108
reinstall.sh
108
reinstall.sh
@ -22,22 +22,6 @@ export LC_ALL=C
|
||||
# 不要漏了最后的 $PATH,否则会找不到 windows 系统程序例如 diskpart
|
||||
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$PATH
|
||||
|
||||
# 如果不是 bash 的话,继续执行会有语法错误,因此在这里判断是否 bash
|
||||
if [ -z "$BASH" ]; then
|
||||
if [ -f /etc/alpine-release ]; then
|
||||
if ! apk add bash; then
|
||||
echo "Error while install bash." >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
if command -v bash >/dev/null; then
|
||||
exec bash "$0" "$@"
|
||||
else
|
||||
echo "Please run this script with bash." >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# 记录日志,过滤含有 password 的行
|
||||
exec > >(tee >(grep -iv password >>/reinstall.log)) 2>&1
|
||||
THIS_SCRIPT=$(readlink -f "$0")
|
||||
@ -51,6 +35,11 @@ trap_err() {
|
||||
sed -n "$line_no"p "$THIS_SCRIPT"
|
||||
}
|
||||
|
||||
if ! { [ -n "$BASH" ] && [ -n "$BASH_VERSION" ]; }; then
|
||||
echo "Please run this script with bash." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
usage_and_exit() {
|
||||
if is_in_windows; then
|
||||
reinstall_____='.\reinstall.bat'
|
||||
@ -64,11 +53,10 @@ Usage: $reinstall_____ anolis 7|8|23
|
||||
oracle 8|9|10
|
||||
almalinux 8|9|10
|
||||
centos 9|10
|
||||
fnos 1
|
||||
nixos 25.11
|
||||
fedora 42|43
|
||||
nixos 25.05
|
||||
debian 9|10|11|12|13
|
||||
alpine 3.20|3.21|3.22|3.23
|
||||
alpine 3.19|3.20|3.21|3.22
|
||||
opensuse 15.6|16.0|tumbleweed
|
||||
openeuler 20.03|22.03|24.03|25.09
|
||||
ubuntu 16.04|18.04|20.04|22.04|24.04|25.10 [--minimal]
|
||||
@ -76,6 +64,7 @@ Usage: $reinstall_____ anolis 7|8|23
|
||||
arch
|
||||
gentoo
|
||||
aosc
|
||||
fnos
|
||||
redhat --img="http://access.cdn.redhat.com/xxx.qcow2"
|
||||
dd --img="http://xxx.com/yyy.zzz" (raw image stores in raw/vhd/tar/gz/xz/zst)
|
||||
windows --image-name="windows xxx yyy" --lang=xx-yy
|
||||
@ -870,7 +859,7 @@ is_have_arm_version() {
|
||||
|
||||
find_windows_iso() {
|
||||
parse_windows_image_name || error_and_exit "--image-name wrong: $image_name"
|
||||
if ! { [ "$version" = 8 ] || [ "$version" = 8.1 ]; } && [ -z "$edition" ]; then
|
||||
if ! [ "$version" = 8.1 ] && [ -z "$edition" ]; then
|
||||
error_and_exit "Edition is not set."
|
||||
fi
|
||||
|
||||
@ -919,8 +908,7 @@ get_windows_iso_link() {
|
||||
x86) echo _ ;;
|
||||
esac
|
||||
;;
|
||||
homebasic | homepremium | ultimate) echo _ ;;
|
||||
business | enterprise) echo "$edition" ;;
|
||||
homebasic | homepremium | business | ultimate) echo _ ;;
|
||||
esac
|
||||
;;
|
||||
7)
|
||||
@ -939,9 +927,10 @@ get_windows_iso_link() {
|
||||
professional | enterprise | ultimate) echo "$edition" ;;
|
||||
esac
|
||||
;;
|
||||
8 | 8.1)
|
||||
# massgrave 不提供 windows 8 下载
|
||||
8.1)
|
||||
case "$edition" in
|
||||
'') echo _ ;; # windows 8.x core
|
||||
'') echo _ ;; # windows 8.1 core
|
||||
pro | enterprise) echo "$edition" ;;
|
||||
esac
|
||||
;;
|
||||
@ -1036,7 +1025,7 @@ get_windows_iso_link() {
|
||||
echo server
|
||||
else
|
||||
case "$version" in
|
||||
vista | 7 | 8 | 8.1 | 10 | 11)
|
||||
vista | 7 | 8.1 | 10 | 11)
|
||||
echo "$version"
|
||||
;;
|
||||
esac
|
||||
@ -1086,10 +1075,7 @@ get_windows_iso_link() {
|
||||
if [ -n "$label_msdl" ]; then
|
||||
iso=$(curl -L "$page_url" | grep -ioP 'https://[^ ]+?#[0-9]+' | head -1 | grep .)
|
||||
else
|
||||
curl -L "$page_url" |
|
||||
tr -d '\n' | sed -e 's,<a ,\n<a ,g' -e 's,</a>,</a>\n,g' | # 使每个 <a></a> 占一行
|
||||
grep -Ei '\.(iso|img)</a>$' | # 找出是 iso 或 img 的行
|
||||
sed -E 's,<a href="?([^" ]+)"?.+>(.+)</a>,\2 \1,' >$tmp/win.list # 提取文件名和链接
|
||||
curl -L "$page_url" | grep -ioP 'https://[^ ]+?.(iso|img)' >$tmp/win.list
|
||||
|
||||
# 如果不是 ltsc ,应该先去除 ltsc 链接,否则最终链接有 ltsc 的
|
||||
# 例如查找 windows 10 iot enterprise,会得到
|
||||
@ -1107,14 +1093,10 @@ get_windows_iso_link() {
|
||||
}
|
||||
|
||||
get_shortest_line() {
|
||||
# awk '{print length($0), $0}' | sort -n | head -1 | awk '{print $2}'
|
||||
awk '(NR == 1 || length($0) < length(shortest)) { shortest = $0 } END { print shortest }'
|
||||
}
|
||||
|
||||
get_shortest_line_by_field() {
|
||||
local field=$1
|
||||
awk "(NR == 1 || length(\$$field) < length(field)) { line = \$0; field = \$$field } END { print line }"
|
||||
}
|
||||
|
||||
get_windows_iso_link_inner() {
|
||||
regexs=()
|
||||
|
||||
@ -1146,9 +1128,7 @@ get_windows_iso_link_inner() {
|
||||
regex=${regex// /_}
|
||||
|
||||
echo "looking for: $regex" >&2
|
||||
if line=$(grep -Ei "^$regex " "$tmp/win.list" | get_shortest_line_by_field 1 | grep .) &&
|
||||
iso=$(awk '{print $2}' <<<"$line" | grep .); then
|
||||
echo "Selected: $line" >&2
|
||||
if iso=$(grep -Ei "/$regex" "$tmp/win.list" | get_shortest_line | grep .); then
|
||||
return
|
||||
fi
|
||||
done
|
||||
@ -1507,8 +1487,8 @@ Continue?
|
||||
dir=distribution/leap/$releasever/appliances
|
||||
case "$releasever" in
|
||||
15.6) file=openSUSE-Leap-$releasever-Minimal-VM.$basearch-Cloud.qcow2 ;;
|
||||
16.0) file=Leap-$releasever-Minimal-VM.$basearch-Cloud.qcow2 ;;
|
||||
# 16.0) file=Leap-$releasever-Minimal-VM.$basearch-kvm$(if [ "$basearch" = x86_64 ]; then echo '-and-xen'; fi).qcow2 ;;
|
||||
# 16.0) file=Leap-$releasever-Minimal-VM.$basearch-Cloud.qcow2 ;; # 缺少 openSUSE-repos-Leap 包,导致没有源
|
||||
16.0) file=Leap-$releasever-Minimal-VM.$basearch-kvm$(if [ "$basearch" = x86_64 ]; then echo '-and-xen'; fi).qcow2 ;;
|
||||
esac
|
||||
|
||||
# https://src.opensuse.org/openSUSE/Leap-Images/src/branch/leap-16.0/kiwi-templates-Minimal/Minimal.kiwi
|
||||
@ -1521,9 +1501,7 @@ Continue?
|
||||
}
|
||||
|
||||
setos_windows() {
|
||||
auto_find_iso=false
|
||||
if [ -z "$iso" ]; then
|
||||
auto_find_iso=true
|
||||
# 查找时将 windows longhorn serverdatacenter 改成 windows server 2008 serverdatacenter
|
||||
image_name=${image_name/windows longhorn server/windows server 2008 server}
|
||||
echo "iso url is not set. Attempting to find it automatically."
|
||||
@ -1537,13 +1515,10 @@ Continue?
|
||||
|
||||
if [[ "$iso" = magnet:* ]]; then
|
||||
: # 不测试磁力链接
|
||||
else
|
||||
iso_is_tested=false
|
||||
if $auto_find_iso; then
|
||||
if test_url_grace "$iso" iso 2>/dev/null; then
|
||||
iso_is_tested=true
|
||||
else
|
||||
# 需要用户输入 massgrave.dev 直链
|
||||
if grep -Eiq '\.massgrave\.dev/.*\.(iso|img)$' <<<"$iso" ||
|
||||
grep -Eiq '\.gravesoft\.dev/#[0-9]+$' <<<"$iso"; then
|
||||
info "Set Direct link"
|
||||
# MobaXterm 不支持
|
||||
# printf '\e]8;;http://example.com\e\\This is a link\e]8;;\e\\\n'
|
||||
@ -1559,11 +1534,9 @@ Continue?
|
||||
error_and_exit "ISO Link is empty."
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if ! $iso_is_tested; then
|
||||
# 测试是否是 iso
|
||||
test_url "$iso" iso
|
||||
fi
|
||||
|
||||
# 判断 iso 架构是否兼容
|
||||
# https://gitlab.com/libosinfo/osinfo-db/-/tree/main/data/os/microsoft.com?ref_type=heads
|
||||
@ -1638,13 +1611,15 @@ Continue with DD?
|
||||
}
|
||||
|
||||
setos_fnos() {
|
||||
if [ "$basearch" = aarch64 ]; then
|
||||
error_and_exit "FNOS not supports ARM."
|
||||
fi
|
||||
|
||||
# 系统盘大小
|
||||
min=8
|
||||
default=8
|
||||
echo "请输入系统分区大小,最小 $min GB,但可能无法更新系统。"
|
||||
echo "Please input System Partition Size. Minimal is $min GB but may not be able to do system updates."
|
||||
while true; do
|
||||
IFS= read -r -p "Size in GB [$default]: " input
|
||||
IFS= read -r -p "Type System Partition Size in GB. Minimal $min GB. [$default]: " input
|
||||
input=${input:-$default}
|
||||
if ! { is_digit "$input" && [ "$input" -ge "$min" ]; }; then
|
||||
error "Invalid Size. Please Try again."
|
||||
@ -1654,15 +1629,7 @@ Continue with DD?
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$basearch" = aarch64 ]; then
|
||||
if [ -z "$iso" ]; then
|
||||
IFS= read -r -p "ISO Link: " iso
|
||||
if [ -z "$iso" ]; then
|
||||
error_and_exit "ISO Link is empty."
|
||||
fi
|
||||
fi
|
||||
else
|
||||
iso=$(curl -L https://fnnas.com/ | grep -o -m1 'https://[^"]*\.iso')
|
||||
iso=$(curl -L https://fnnas.com/ | grep -o 'https://[^"]*\.iso' | head -1 | grep .)
|
||||
|
||||
# curl 7.82.0+
|
||||
# curl -L --json '{"url":"'$iso'"}' https://www.fnnas.com/api/download-sign
|
||||
@ -1672,7 +1639,6 @@ Continue with DD?
|
||||
-H 'Content-Type: application/json' \
|
||||
https://www.fnnas.com/api/download-sign |
|
||||
grep -o 'https://[^"]*')
|
||||
fi
|
||||
|
||||
test_url "$iso" iso
|
||||
eval "${step}_iso='$iso'"
|
||||
@ -1941,12 +1907,11 @@ verify_os_name() {
|
||||
'almalinux 8|9|10' \
|
||||
'rocky 8|9|10' \
|
||||
'oracle 8|9|10' \
|
||||
'fnos 1' \
|
||||
'fedora 42|43' \
|
||||
'nixos 25.11' \
|
||||
'nixos 25.05' \
|
||||
'debian 9|10|11|12|13' \
|
||||
'opensuse 15.6|16.0|tumbleweed' \
|
||||
'alpine 3.20|3.21|3.22|3.23' \
|
||||
'alpine 3.19|3.20|3.21|3.22' \
|
||||
'openeuler 20.03|22.03|24.03|25.09' \
|
||||
'ubuntu 16.04|18.04|20.04|22.04|24.04|25.10' \
|
||||
'redhat' \
|
||||
@ -1954,6 +1919,7 @@ verify_os_name() {
|
||||
'arch' \
|
||||
'gentoo' \
|
||||
'aosc' \
|
||||
'fnos' \
|
||||
'windows' \
|
||||
'dd' \
|
||||
'netboot.xyz'; do
|
||||
@ -2377,6 +2343,10 @@ prompt_password() {
|
||||
warn false "Leave blank to use a random password."
|
||||
warn false "不填写则使用随机密码"
|
||||
while true; do
|
||||
# 特殊字符列表
|
||||
# https://learn.microsoft.com/previous-versions/windows/it-pro/windows-server-2012-r2-and-2012/hh994562(v=ws.11)
|
||||
chars=\''A-Za-z0-9~!@#$%^&*_=+`|(){}[]:;"<>,.?/-'
|
||||
random_password=$(tr -dc "$chars" </dev/random | head -c16)
|
||||
IFS= read -r -p "Password: " password
|
||||
if [ -n "$password" ]; then
|
||||
IFS= read -r -p "Retype password: " password_confirm
|
||||
@ -2386,11 +2356,7 @@ prompt_password() {
|
||||
error "Passwords don't match. Try again."
|
||||
fi
|
||||
else
|
||||
# 特殊字符列表
|
||||
# https://learn.microsoft.com/previous-versions/windows/it-pro/windows-server-2012-r2-and-2012/hh994562(v=ws.11)
|
||||
# 有的机器运行 centos 7 ,用 /dev/random 产生 16 位密码,开启了 rngd 也要 5 秒,关闭了 rngd 则长期阻塞
|
||||
chars=\''A-Za-z0-9~!@#$%^&*_=+`|(){}[]:;"<>,.?/-'
|
||||
password=$(tr -dc "$chars" </dev/urandom | head -c16)
|
||||
password=$random_password
|
||||
break
|
||||
fi
|
||||
done
|
||||
@ -4038,7 +4004,7 @@ EOF
|
||||
|
||||
# https://manpages.debian.org/testing/openssh-server/authorized_keys.5.en.html#AUTHORIZED_KEYS_FILE_FORMAT
|
||||
is_valid_ssh_key() {
|
||||
grep -qE '^(ecdsa-sha2-nistp(256|384|521)|ssh-(ed25519|rsa)) ' <<<"$1"
|
||||
grep -qE '^(ecdsa-sha2-nistp(256|384|512)|ssh-(ed25519|rsa)) ' <<<"$1"
|
||||
}
|
||||
|
||||
[ -n "$2" ] || ssh_key_error_and_exit "Need value for $1"
|
||||
|
||||
264
trans.sh
264
trans.sh
@ -414,31 +414,23 @@ extract_env_from_cmdline() {
|
||||
}
|
||||
|
||||
ensure_service_started() {
|
||||
local service=$1
|
||||
service=$1
|
||||
|
||||
if ! rc-service -q "$service" start; then
|
||||
for i in $(seq 10); do
|
||||
if [ "$service" = modloop ]; then
|
||||
# 避免有时 modloop 下载不完整导致报错
|
||||
# * Failed to verify signature of !
|
||||
# mount: mounting /dev/loop0 on /.modloop failed: Invalid argument
|
||||
rm -f /lib/modloop-lts /lib/modloop-virt
|
||||
fi
|
||||
if rc-service -q "$service" start; then
|
||||
return
|
||||
fi
|
||||
sleep 5
|
||||
done
|
||||
if ! rc-service -q $service status; then
|
||||
if ! retry 5 rc-service -q $service start; then
|
||||
error_and_exit "Failed to start $service."
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
ensure_service_stopped() {
|
||||
local service=$1
|
||||
service=$1
|
||||
|
||||
if ! retry 10 5 rc-service -q "$service" stop; then
|
||||
if rc-service -q $service status; then
|
||||
if ! retry 5 rc-service -q $service stop; then
|
||||
error_and_exit "Failed to stop $service."
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
mod_motd() {
|
||||
@ -1638,9 +1630,9 @@ install_nixos() {
|
||||
fi
|
||||
|
||||
# 备用方案
|
||||
# 1. 从 https://mirror.nju.edu.cn/nix-channels/nixos-25.11/nixexprs.tar.xz 获取
|
||||
# https://github.com/NixOS/nixpkgs/blob/nixos-25.11/pkgs/tools/package-management/nix/default.nix
|
||||
# https://github.com/NixOS/nixpkgs/blob/nixos-25.11/nixos/modules/installer/tools/nix-fallback-paths.nix
|
||||
# 1. 从 https://mirror.nju.edu.cn/nix-channels/nixos-25.05/nixexprs.tar.xz 获取
|
||||
# https://github.com/NixOS/nixpkgs/blob/nixos-25.05/pkgs/tools/package-management/nix/default.nix
|
||||
# https://github.com/NixOS/nixpkgs/blob/nixos-25.05/nixos/modules/installer/tools/nix-fallback-paths.nix
|
||||
# 2. 安装最新版 nix,添加 nixos channel 后获取
|
||||
# nix eval -f '<nixpkgs>' --raw 'nixVersions.stable.version' --extra-experimental-features nix-command
|
||||
|
||||
@ -1876,11 +1868,8 @@ add_frpc_systemd_service_if_need() {
|
||||
# 下载 frpc
|
||||
# 注意下载的 frpc owner 不是 root:root
|
||||
frpc_url=$(get_frpc_url linux)
|
||||
basename=$(echo "$frpc_url" | awk -F/ '{print $NF}' | sed 's/\.tar\.gz//')
|
||||
download "$frpc_url" "$os_dir/frpc.tar.gz"
|
||||
# busybox tar 不支持 wildcard
|
||||
# tar: */frpc: not found in archive
|
||||
tar xzf "$os_dir/frpc.tar.gz" "$basename/frpc" -O >"$os_dir/usr/local/bin/frpc"
|
||||
tar xzf "$os_dir/frpc.tar.gz" "*/frpc" -O >"$os_dir/usr/local/bin/frpc"
|
||||
rm -f "$os_dir/frpc.tar.gz"
|
||||
chmod a+x "$os_dir/usr/local/bin/frpc"
|
||||
|
||||
@ -2439,7 +2428,7 @@ get_disk_logic_sector_size() {
|
||||
}
|
||||
|
||||
is_4kn() {
|
||||
[ "$(blockdev --getss "/dev/$xda")" = 4096 ]
|
||||
[ "$(blockdev --getss "$1")" = 4096 ]
|
||||
}
|
||||
|
||||
is_xda_gt_2t() {
|
||||
@ -2531,18 +2520,15 @@ create_part() {
|
||||
sector_size=$(get_disk_logic_sector_size /dev/$xda)
|
||||
total_sector_count=$(get_disk_sector_count /dev/$xda)
|
||||
|
||||
# 截止最后一个分区的总扇区数(也就是总硬盘扇区数 - 备份分区表扇区数 - 备份 GPT Header)
|
||||
if ! is_efi && ! is_xda_gt_2t; then
|
||||
# mbr
|
||||
total_sector_count_except_backup_gpt=$total_sector_count
|
||||
elif is_4kn; then
|
||||
total_sector_count_except_backup_gpt=$((total_sector_count - 4 - 1))
|
||||
# 截止最后一个分区的总扇区数(也就是总硬盘扇区数 - 备份分区表扇区数)
|
||||
if is_efi; then
|
||||
total_sector_count_except_backup_gpt=$((total_sector_count - 33))
|
||||
else
|
||||
total_sector_count_except_backup_gpt=$((total_sector_count - 32 - 1))
|
||||
total_sector_count_except_backup_gpt=$total_sector_count
|
||||
fi
|
||||
|
||||
# 向下取整 MiB
|
||||
# gpt 最后 33 (512n/512e) 或 5 (4Kn) 个扇区是备份分区表,不可用
|
||||
# gpt 最后 33 个扇区是备份分区表,不可用
|
||||
# parted 结束位置填 100% 时也会忽略最后不足 1MiB 的部分,我们模仿它
|
||||
max_can_use_m=$((total_sector_count_except_backup_gpt * sector_size / 1024 / 1024))
|
||||
|
||||
@ -2571,20 +2557,9 @@ create_part() {
|
||||
|
||||
mkfs.fat /dev/$xda*1 #1 efi
|
||||
mkfs.ext4 -F $ext4_opts /dev/$xda*2 #2 os + installer
|
||||
elif is_xda_gt_2t; then
|
||||
# bios > 2t
|
||||
# 官方安装器是 mkpart BOOT 1M 100M,无论 esp 或者 bios_grub 都用这个分区和大小
|
||||
parted /dev/$xda -s -- \
|
||||
mklabel gpt \
|
||||
mkpart BOOT ext4 1MiB 101MiB \
|
||||
mkpart SYSTEM ext4 101MiB $os_part_end \
|
||||
set 1 bios_grub on
|
||||
update_part
|
||||
|
||||
echo #1 bios_boot
|
||||
mkfs.ext4 -F $ext4_opts /dev/$xda*2 #2 os + installer
|
||||
else
|
||||
# bios
|
||||
# 官方安装器不支持 bios + >2t
|
||||
parted /dev/$xda -s -- \
|
||||
mklabel msdos \
|
||||
mkpart primary 1MiB 101MiB \
|
||||
@ -2778,6 +2753,14 @@ mount_pseudo_fs() {
|
||||
fi
|
||||
}
|
||||
|
||||
get_yq_name() {
|
||||
if grep -q '3\.1[6789]' /etc/alpine-release; then
|
||||
echo yq
|
||||
else
|
||||
echo yq-go
|
||||
fi
|
||||
}
|
||||
|
||||
create_cloud_init_network_config() {
|
||||
ci_file=$1
|
||||
recognize_static6=${2:-true}
|
||||
@ -2789,7 +2772,7 @@ create_cloud_init_network_config() {
|
||||
mkdir -p "$(dirname "$ci_file")"
|
||||
touch "$ci_file"
|
||||
|
||||
apk add yq-go
|
||||
apk add "$(get_yq_name)"
|
||||
|
||||
need_set_dns4=false
|
||||
need_set_dns6=false
|
||||
@ -2903,7 +2886,7 @@ create_cloud_init_network_config() {
|
||||
yq -i "del(.network.config[$config_id] | select(has(\"address\") | not))" $ci_file
|
||||
fi
|
||||
|
||||
apk del yq-go
|
||||
apk del "$(get_yq_name)"
|
||||
|
||||
# 查看文件
|
||||
info "Cloud-init network config"
|
||||
@ -3248,32 +3231,25 @@ chroot_systemctl_disable() {
|
||||
done
|
||||
}
|
||||
|
||||
remove_or_disable_cloud_init() {
|
||||
remove_cloud_init() {
|
||||
os_dir=$1
|
||||
|
||||
if ! is_have_cmd_on_disk $os_dir cloud-init; then
|
||||
return
|
||||
fi
|
||||
|
||||
info "Remove or Disable Cloud-Init"
|
||||
info "Remove Cloud-Init"
|
||||
|
||||
# ubuntu-server-minimal ubuntu-cloud-minimal 都包含 cloud-init
|
||||
# 用 iso 安装的 ubuntu 也有 cloud-init
|
||||
# 因此不删除 ubuntu 的 cloud-init,而是禁用它
|
||||
|
||||
# iso 安装首次启动是通过 /etc/cloud/cloud.cfg.d/99-installer.cfg 初始化系统,包括:
|
||||
# 1. 创建普通用户和密码,添加 ssh 登录公钥
|
||||
# 2. 创建 /etc/cloud/cloud-init.disabled
|
||||
|
||||
if grep -iq ubuntu $os_dir/etc/os-release; then
|
||||
# 模仿 iso 安装的 ubuntu,只创建 cloud-init.disabled,不禁用服务
|
||||
# 两种方法都可以
|
||||
if false && [ -d $os_dir/etc/cloud ]; then
|
||||
touch $os_dir/etc/cloud/cloud-init.disabled
|
||||
else
|
||||
fi
|
||||
|
||||
# systemctl is-enabled cloud-init-hotplugd.service 状态是 static
|
||||
# disable 会出现一堆提示信息,也无法 disable
|
||||
for unit in $(
|
||||
chroot $os_dir systemctl list-unit-files |
|
||||
grep -E '^(cloud-init|cloud-init-.*|cloud-config|cloud-final)\.(service|socket)' | grep enabled | awk '{print $1}'
|
||||
grep -E '^(cloud-init-.*|cloud-config|cloud-final)\.(service|socket)' | grep enabled | awk '{print $1}'
|
||||
); do
|
||||
# 服务不存在时会报错
|
||||
if chroot $os_dir systemctl -q is-enabled "$unit"; then
|
||||
@ -3290,7 +3266,7 @@ remove_or_disable_cloud_init() {
|
||||
;;
|
||||
zypper)
|
||||
# 加上 -u 才会删除依赖
|
||||
chroot $os_dir zypper remove -y -u cloud-init cloud-init-config-suse
|
||||
chroot $os_dir zypper remove -y -u cloud-init
|
||||
;;
|
||||
apt-get)
|
||||
# ubuntu 25.04 开始有 cloud-init-base
|
||||
@ -3301,7 +3277,6 @@ remove_or_disable_cloud_init() {
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
disable_jeos_firstboot() {
|
||||
@ -3417,7 +3392,7 @@ EOF
|
||||
if [ "$distro" = fedora ] && [ "$releasever" = 43 ]; then
|
||||
chroot $os_dir dnf mark user netcat -y
|
||||
fi
|
||||
remove_or_disable_cloud_init $os_dir
|
||||
remove_cloud_init $os_dir
|
||||
|
||||
disable_selinux $os_dir
|
||||
disable_kdump $os_dir
|
||||
@ -3444,7 +3419,7 @@ EOF
|
||||
find_and_mount /boot
|
||||
find_and_mount /boot/efi
|
||||
|
||||
remove_or_disable_cloud_init $os_dir
|
||||
remove_cloud_init $os_dir
|
||||
|
||||
# 获取当前开启的 Components, 后面要用
|
||||
if [ -f $os_dir/etc/apt/sources.list.d/debian.sources ]; then
|
||||
@ -3496,8 +3471,10 @@ EOF
|
||||
! sh /can_use_cloud_kernel.sh "$xda" $(get_eths); then
|
||||
kernel_package=$(echo "$kernel_package" | sed 's/-cloud//')
|
||||
fi
|
||||
|
||||
# 该方法包含了 apt-mark manual
|
||||
# 如果镜像自带内核跟最佳内核是同一种且有更新
|
||||
# 则 apt install 只会进行更新,不会将包设置成 manual
|
||||
# 需要再运行 apt install 才会将包设置成 manual
|
||||
chroot_apt_install $os_dir "$kernel_package"
|
||||
chroot_apt_install $os_dir "$kernel_package"
|
||||
|
||||
# 使用 autoremove 删除非最佳内核
|
||||
@ -3678,35 +3655,24 @@ EOF
|
||||
fi
|
||||
|
||||
# rpm -qi 不支持通配符
|
||||
origin_kernel=$(chroot $os_dir rpm -qa 'kernel-*' --qf '%{NAME}\n' | grep -v firmware)
|
||||
if ! [ "$(echo "$origin_kernel" | wc -l)" -eq 1 ]; then
|
||||
error_and_exit "Unexpected kernel installed: $origin_kernel"
|
||||
installed_kernel=$(chroot $os_dir rpm -qa 'kernel-*' --qf '%{NAME}\n' | grep -v firmware)
|
||||
if ! [ "$(echo "$installed_kernel" | wc -l)" -eq 1 ]; then
|
||||
error_and_exit "Unexpected kernel installed: $installed_kernel"
|
||||
fi
|
||||
|
||||
# 16.0 能同时装 kernel-default-base 和 kernel-default
|
||||
# tw 不能同时装 kernel-default-base 和 kernel-default
|
||||
# 不能同时装 kernel-default-base 和 kernel-default
|
||||
# 因此需要添加 --force-resolution 自动删除 kernel-default-base
|
||||
if ! [ "$origin_kernel" = "$target_kernel" ]; then
|
||||
if ! [ "$installed_kernel" = "$target_kernel" ]; then
|
||||
# x86 必须设置一个密码,否则报错,arm 没有这个问题
|
||||
# Failed to get root password hash
|
||||
# Failed to import /etc/uefi/certs/76B6A6A0.crt
|
||||
# warning: %post(kernel-default-5.14.21-150500.55.83.1.x86_64) scriptlet failed, exit status 255
|
||||
need_password_workaround=false
|
||||
if grep -q '^root:[:!*]' $os_dir/etc/shadow; then
|
||||
need_password_workaround=true
|
||||
fi
|
||||
|
||||
if $need_password_workaround; then
|
||||
echo "root:$(mkpasswd '')" | chroot $os_dir chpasswd -e
|
||||
fi
|
||||
# 安装新内核
|
||||
chroot $os_dir zypper install -y --force-resolution $target_kernel
|
||||
# 删除旧内核
|
||||
if chroot $os_dir rpm -q $origin_kernel; then
|
||||
chroot $os_dir zypper remove -y --force-resolution $origin_kernel
|
||||
fi
|
||||
if $need_password_workaround; then
|
||||
chroot $os_dir passwd -d root
|
||||
else
|
||||
chroot $os_dir zypper install -y --force-resolution $target_kernel
|
||||
fi
|
||||
fi
|
||||
|
||||
@ -3717,7 +3683,7 @@ EOF
|
||||
|
||||
# 最后才删除 cloud-init
|
||||
# 因为生成 sysconfig 网络配置要用目标系统的 cloud-init
|
||||
remove_or_disable_cloud_init $os_dir
|
||||
remove_cloud_init $os_dir
|
||||
|
||||
restore_resolv_conf $os_dir
|
||||
fi
|
||||
@ -4198,7 +4164,7 @@ chroot_dnf() {
|
||||
}
|
||||
|
||||
chroot_apt_update() {
|
||||
local os_dir=$1
|
||||
os_dir=$1
|
||||
|
||||
current_hash=$(cat $os_dir/etc/apt/sources.list $os_dir/etc/apt/sources.list.d/*.sources 2>/dev/null | md5sum)
|
||||
if ! [ "$saved_hash" = "$current_hash" ]; then
|
||||
@ -4208,30 +4174,15 @@ chroot_apt_update() {
|
||||
}
|
||||
|
||||
chroot_apt_install() {
|
||||
local os_dir=$1
|
||||
os_dir=$1
|
||||
shift
|
||||
|
||||
# 只安装未安装的软件包
|
||||
# 避免更新浪费时间
|
||||
local pkg='' pkgs=''
|
||||
for pkg in "$@"; do
|
||||
if chroot $os_dir dpkg -s "$pkg" >/dev/null 2>&1; then
|
||||
# 如果已安装则标记为 manual,防止被 autoremove 删除
|
||||
chroot $os_dir apt-mark manual "$pkg"
|
||||
else
|
||||
pkgs="$pkgs $pkg"
|
||||
fi
|
||||
done
|
||||
|
||||
# 一次性安装,避免多次 update-initramfs
|
||||
if [ -n "$pkgs" ]; then
|
||||
chroot_apt_update $os_dir
|
||||
DEBIAN_FRONTEND=noninteractive chroot $os_dir apt-get install -y $pkgs
|
||||
fi
|
||||
DEBIAN_FRONTEND=noninteractive chroot $os_dir apt-get install -y "$@"
|
||||
}
|
||||
|
||||
chroot_apt_remove() {
|
||||
local os_dir=$1
|
||||
os_dir=$1
|
||||
shift
|
||||
|
||||
# minimal 镜像 删除 grub-pc 时会安装 grub-efi-amd64
|
||||
@ -4254,7 +4205,7 @@ chroot_apt_remove() {
|
||||
}
|
||||
|
||||
chroot_apt_autoremove() {
|
||||
local os_dir=$1
|
||||
os_dir=$1
|
||||
|
||||
change_confs() {
|
||||
action=$1
|
||||
@ -4345,14 +4296,7 @@ install_fnos() {
|
||||
mkdir -p $initrd_dir
|
||||
(
|
||||
cd $initrd_dir
|
||||
suffix=$(
|
||||
case $(uname -m) in
|
||||
x86_64) echo amd ;;
|
||||
aarch64) echo a64 ;;
|
||||
*) ;;
|
||||
esac
|
||||
)
|
||||
zcat /iso/install.$suffix/initrd.gz | cpio -idm
|
||||
zcat /iso/install.amd/initrd.gz | cpio -idm
|
||||
)
|
||||
apk del cpio
|
||||
|
||||
@ -4388,6 +4332,9 @@ install_fnos() {
|
||||
# 挂载 proc sys dev
|
||||
mount_pseudo_fs /os
|
||||
|
||||
# 更新 initrd
|
||||
# chroot $os_dir update-initramfs -u
|
||||
|
||||
# 更改密码
|
||||
if is_need_set_ssh_keys; then
|
||||
set_ssh_keys_and_del_password $os_dir
|
||||
@ -4401,31 +4348,6 @@ install_fnos() {
|
||||
chroot $os_dir systemctl enable ssh
|
||||
fi
|
||||
|
||||
# fstab
|
||||
{
|
||||
# /
|
||||
uuid=$(lsblk /dev/$xda*2 -no UUID)
|
||||
echo "$fstab_line_os" | sed "s/%s/$uuid/"
|
||||
|
||||
# swapfile
|
||||
# 官方安装器即使 swapfile 设为 0 也会有这行
|
||||
echo "$fstab_line_swapfile"
|
||||
|
||||
# /boot/efi
|
||||
if is_efi; then
|
||||
uuid=$(lsblk /dev/$xda*1 -no UUID)
|
||||
echo "$fstab_line_efi" | sed "s/%s/$uuid/"
|
||||
fi
|
||||
} >$os_dir/etc/fstab
|
||||
|
||||
# 更新 initrd,官方安装器也有这一步
|
||||
# 理论上 /var/tmp 要设置 1777 权限,但飞牛官方安装器安装后不是
|
||||
# 需要先创建 /etc/fstab ,否则会有以下警告
|
||||
# W: Couldn't identify type of root file system for fsck hook
|
||||
mkdir -p $os_dir/var/tmp
|
||||
chmod 1777 $os_dir/var/tmp
|
||||
chroot $os_dir update-initramfs -u
|
||||
|
||||
# grub
|
||||
if is_efi; then
|
||||
chroot $os_dir grub-install --efi-directory=/boot/efi
|
||||
@ -4434,16 +4356,28 @@ install_fnos() {
|
||||
chroot $os_dir grub-install /dev/$xda
|
||||
fi
|
||||
|
||||
# grub 配置
|
||||
# 取自 strings trim-install | grep GRUB_DISTRIBUTOR
|
||||
sed -i 's/^GRUB_DISTRIBUTOR=.*/GRUB_DISTRIBUTOR="FNOS"/' $os_dir/etc/default/grub
|
||||
|
||||
# grub tty
|
||||
ttys_cmdline=$(get_ttys console=)
|
||||
echo GRUB_CMDLINE_LINUX=\"\$GRUB_CMDLINE_LINUX $ttys_cmdline\" >$os_dir/etc/default/grub.d/tty.cfg
|
||||
|
||||
echo GRUB_CMDLINE_LINUX=\"\$GRUB_CMDLINE_LINUX $ttys_cmdline\" \
|
||||
>>$os_dir/etc/default/grub.d/tty.cfg
|
||||
chroot $os_dir update-grub
|
||||
|
||||
# fstab
|
||||
{
|
||||
# /
|
||||
uuid=$(lsblk /dev/$xda*2 -no UUID)
|
||||
echo "$fstab_line_os" | sed "s/%s/$uuid/"
|
||||
|
||||
# 官方安装器即使 swapfile 设为 0 也会有这行
|
||||
echo "$fstab_line_swapfile" | sed "s/%s/$uuid/"
|
||||
|
||||
# /boot/efi
|
||||
if is_efi; then
|
||||
uuid=$(lsblk /dev/$xda*1 -no UUID)
|
||||
echo "$fstab_line_efi" | sed "s/%s/$uuid/"
|
||||
fi
|
||||
} >$os_dir/etc/fstab
|
||||
|
||||
# 网卡配置
|
||||
create_cloud_init_network_config /net.cfg
|
||||
create_network_manager_config /net.cfg $os_dir
|
||||
@ -4803,13 +4737,10 @@ EOF
|
||||
# 安装最佳内核
|
||||
flavor=$(get_ubuntu_kernel_flavor)
|
||||
echo "Use kernel flavor: $flavor"
|
||||
|
||||
# 题外话
|
||||
# 如果某个包是 auto 状态且有更新
|
||||
# 则 apt install PKG 只会进行更新,不会将包设置成 manual
|
||||
# 需要再次运行 apt install PKG 才会将包设置成 manual
|
||||
|
||||
# 该方法包含了 apt-mark manual
|
||||
# 如果镜像自带内核跟最佳内核是同一种且有更新
|
||||
# 则 apt install 只会进行更新,不会将包设置成 manual
|
||||
# 需要再运行 apt install 才会将包设置成 manual
|
||||
chroot_apt_install $os_dir "linux-image-$flavor"
|
||||
chroot_apt_install $os_dir "linux-image-$flavor"
|
||||
|
||||
# 使用 autoremove 删除多余内核
|
||||
@ -5145,7 +5076,7 @@ EOF
|
||||
|
||||
# 最后才删除 cloud-init
|
||||
# 因为生成 netplan/sysconfig 网络配置要用目标系统的 cloud-init
|
||||
remove_or_disable_cloud_init /os
|
||||
remove_cloud_init /os
|
||||
|
||||
# 删除 swapfile
|
||||
swapoff -a
|
||||
@ -5611,6 +5542,12 @@ is_list_has() {
|
||||
echo "$list" | grep -qFx "$item"
|
||||
}
|
||||
|
||||
# hivexget 是 shell 脚本,开头是 #!/bin/bash
|
||||
# 但 alpine 没安装 bash,直接运行 hivexget 会报错
|
||||
hivexget() {
|
||||
ash "$(which hivexget)" "$@"
|
||||
}
|
||||
|
||||
get_windows_type_from_windows_drive() {
|
||||
local os_dir=$1
|
||||
|
||||
@ -6064,18 +6001,8 @@ install_windows() {
|
||||
echo https://downloadmirror.intel.com/849483/Wired_driver_30.0.1_${arch_intel}.zip
|
||||
;;
|
||||
x64)
|
||||
id=$(
|
||||
case "$product_ver" in
|
||||
10) echo 18293 ;;
|
||||
11) echo 727998 ;;
|
||||
2016) echo 18737 ;;
|
||||
2019) echo 19372 ;;
|
||||
2022) echo 706171 ;;
|
||||
2025) echo 838943 ;;
|
||||
esac
|
||||
)
|
||||
# intel 禁止了 wget 下载网页
|
||||
wget -U curl/7.54.1 https://www.intel.com/content/www/us/en/download/$id.html -O- |
|
||||
wget -U curl/7.54.1 https://www.intel.com/content/www/us/en/download/727998.html -O- |
|
||||
grep -Eio -m1 "\"https://.+/(Wired_driver|prowin).*${arch_intel}(legacy)?\.(zip|exe)\"" | tr -d '"' | grep .
|
||||
;;
|
||||
esac ;;
|
||||
@ -6685,17 +6612,12 @@ EOF
|
||||
done
|
||||
|
||||
if ! $is_gen11 && [ "$build_ver" -ge 19041 ]; then
|
||||
# RST v20
|
||||
local page=https://www.intel.com/content/www/us/en/download/849936.html
|
||||
url=https://downloadmirror.intel.com/865363/SetupRST.exe # RST v20
|
||||
elif [ "$build_ver" -ge 15063 ]; then
|
||||
# RST v19
|
||||
local page=https://www.intel.com/content/www/us/en/download/849933.html
|
||||
url=https://downloadmirror.intel.com/849934/SetupRST.exe # RST v19
|
||||
else
|
||||
error_and_exit "can't find suitable vmd driver"
|
||||
fi
|
||||
local url
|
||||
url=$(wget -U curl/7.54.1 "$page" -O- |
|
||||
grep -Eio -m1 "\"https://.+/SetupRST\.exe\"" | tr -d '"' | grep .)
|
||||
|
||||
# 注意 intel 禁止了 aria2 下载
|
||||
download $url $drv/SetupRST.exe
|
||||
@ -6861,7 +6783,7 @@ EOF
|
||||
|
||||
# 4kn EFI 分区最少要 260M
|
||||
# https://learn.microsoft.com/windows-hardware/manufacture/desktop/hard-drives-and-partitions
|
||||
if is_4kn; then
|
||||
if is_4kn /dev/$xda; then
|
||||
sed -i 's/is4kn=0/is4kn=1/i' $startnet_cmd
|
||||
fi
|
||||
|
||||
|
||||
Reference in New Issue
Block a user