Compare commits

..

19 Commits

Author SHA1 Message Date
e60a8d0de2 core: 修复 azure 开启加速网络时 NetworkManager 无法获取 IP
fixes #499
2025-12-04 22:56:16 +08:00
2a561f0d8c core: 添加 alpine 3.23, nixos 25.11 2025-12-04 19:43:54 +08:00
586eb5dee1 opensuse: 16.0 重新使用 cloud 镜像 2025-12-04 19:43:53 +08:00
c94f334663 core: 用 sh 运行时自动切换成 bash 2025-12-04 19:43:52 +08:00
bd5e118570 core: 修复 ECDSA-P521 设置报错 (#480)
fixes #479
2025-11-10 19:37:18 +08:00
78ba0690f9 windows: 添加 win8 链接 2025-11-04 22:17:11 +08:00
9e0968eabd windows: 从网页获取 intel vmd 驱动最新链接 2025-11-04 22:15:18 +08:00
3263ea3875 core: 改成使用 /dev/urandom 以修复生成随机密码时阻塞
fixes #469
fixes #471
2025-11-04 21:54:21 +08:00
7c19559d86 core: 日志显示使用缓冲区,避免卡顿 2025-10-31 07:50:45 +08:00
8b838f8871 core: 不重要的优化 2025-10-31 07:50:45 +08:00
5bf00edeed windows: 调整 intel nic 驱动
win7: 统一使用 25.0,即使镜像不支持 sha256,因为官网下架了旧版本驱动
win10: 不再固定版本,而是从网页获取最新版
2025-10-31 07:50:44 +08:00
85637edc5b windows: 优化镜像查找 2025-10-31 07:50:43 +08:00
baa430eb10 core: --frpc-toml 允许使用 http 链接 2025-10-31 07:50:43 +08:00
66f3173c7b core: alpine initrd 使用 udhcpc
dhcpcd 会配置租约时间,过期会移除 IP,但我们的没有在后台运行 dhcpcd ,因此用 udhcpc
2025-10-31 07:50:42 +08:00
af84ac0b3c core: 默认使用随机密码 2025-10-31 07:50:41 +08:00
57a88a6bd9 windows: 从注册表读取系统版本号
windows 10 22h2 版本号是 19045
但 exe 版本号是 19041
2025-10-31 07:50:41 +08:00
24a4446a02 debian: 支持在安装过程中开启 ssh 2025-10-31 07:50:40 +08:00
780e1a694f fedora: 添加 43 2025-10-29 00:06:54 +08:00
43ba86076f windows: 修复无法查找 win11 pro arm iso
fixes #460
2025-10-28 23:21:41 +08:00
10 changed files with 710 additions and 303 deletions

View File

@ -46,7 +46,7 @@ The system requirements for the target system are as follows:
| System | Version | Memory | Disk | | System | Version | Memory | Disk |
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------- | --------- | ---------------- | | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------- | --------- | ---------------- |
| <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.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.debian.org/favicon.ico" /> Debian | 9, 10, 11, 12, 13 | 256 MB | 1 ~ 1.5 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://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 | | <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 |
@ -54,14 +54,14 @@ The system requirements for the target system are as follows:
| <img width="16" height="16" src="https://www.redhat.com/favicon.ico" /> RHEL &nbsp;<img width="16" height="16" src="https://almalinux.org/fav/favicon.ico" /> AlmaLinux &nbsp;<img width="16" height="16" src="https://rockylinux.org/favicon.png" /> Rocky &nbsp;<img width="16" height="16" src="https://www.oracle.com/asset/web/favicons/favicon-32.png" /> Oracle | 8, 9, 10 | 512 MB \* | 5 GB | | <img width="16" height="16" src="https://www.redhat.com/favicon.ico" /> RHEL &nbsp;<img width="16" height="16" src="https://almalinux.org/fav/favicon.ico" /> AlmaLinux &nbsp;<img width="16" height="16" src="https://rockylinux.org/favicon.png" /> Rocky &nbsp;<img width="16" height="16" src="https://www.oracle.com/asset/web/favicons/favicon-32.png" /> Oracle | 8, 9, 10 | 512 MB \* | 5 GB |
| <img width="16" height="16" src="https://opencloudos.org/qq.ico" /> OpenCloudOS | 8, 9, Stream 23 | 512 MB \* | 5 GB | | <img width="16" height="16" src="https://opencloudos.org/qq.ico" /> OpenCloudOS | 8, 9, Stream 23 | 512 MB \* | 5 GB |
| <img width="16" height="16" src="https://www.centos.org/assets/icons/favicon.svg" /> CentOS Stream | 9, 10 | 512 MB \* | 5 GB | | <img width="16" height="16" src="https://www.centos.org/assets/icons/favicon.svg" /> CentOS Stream | 9, 10 | 512 MB \* | 5 GB |
| <img width="16" height="16" src="https://fedoraproject.org/favicon.ico" /> Fedora | 41, 42 | 512 MB \* | 5 GB | | <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://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://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.05 | 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://archlinux.org/static/favicon.png" /> Arch | Rolling | 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://www.gentoo.org/assets/img/logo/gentoo-g.png" /> Gentoo | Rolling | 512 MB | 5 GB |
| <img width="16" height="16" src="https://aosc.io/assets/distros/aosc-os.svg" /> AOSC OS | 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 | Beta | 512 MB | 8 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://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 (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) | 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 | | <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 |
@ -145,7 +145,7 @@ certutil -urlcache -f -split https://cnb.cool/bin456789/reinstall/-/git/raw/main
> >
> Data is priceless — please think twice before proceeding! > Data is priceless — please think twice before proceeding!
- The username is `root` with a default password of `123@@@`. - Username `root`. The script prompts for a password. If left blank, a random one is generated.
- When installing the latest version, the version number does not need to be specified. - 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. - 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. - Automatically selects different optimized kernels based on machine type, such as `Cloud` or `HWE` kernels.
@ -159,10 +159,11 @@ bash reinstall.sh anolis 7|8|23
almalinux 8|9|10 almalinux 8|9|10
opencloudos 8|9|23 opencloudos 8|9|23
centos 9|10 centos 9|10
fedora 41|42 fnos 1
nixos 25.05 nixos 25.11
fedora 42|43
debian 9|10|11|12|13 debian 9|10|11|12|13
alpine 3.19|3.20|3.21|3.22 alpine 3.20|3.21|3.22|3.23
opensuse 15.6|16.0|tumbleweed opensuse 15.6|16.0|tumbleweed
openeuler 20.03|22.03|24.03|25.09 openeuler 20.03|22.03|24.03|25.09
ubuntu 16.04|18.04|20.04|22.04|24.04|25.10 [--minimal] ubuntu 16.04|18.04|20.04|22.04|24.04|25.10 [--minimal]
@ -170,7 +171,6 @@ bash reinstall.sh anolis 7|8|23
arch arch
gentoo gentoo
aosc aosc
fnos
redhat --img="http://access.cdn.redhat.com/xxx.qcow2" redhat --img="http://access.cdn.redhat.com/xxx.qcow2"
``` ```
@ -180,14 +180,17 @@ bash reinstall.sh anolis 7|8|23
- `--ssh-key KEY` Set up SSH login public key, [formatted as follows](#--ssh-key). When using public key, password is empty. - `--ssh-key KEY` Set up SSH login public key, [formatted as follows](#--ssh-key). When using public key, password is empty.
- `--ssh-port PORT` Change the SSH port (for log observation during installation and for the new system) - `--ssh-port PORT` Change the SSH port (for log observation during installation and for the new system)
- `--web-port PORT` Change the Web port (for log observation during installation only) - `--web-port PORT` Change the Web port (for log observation during installation only)
- `--frpc-toml /path/to/frpc.toml` Add frpc for intranet tunneling - `--frpc-toml PATH` Add frpc for intranet tunneling. Parameter can be local filepath or HTTP URL
- `--hold 2` Prevent reboot after installation completes, allowing SSH login to modify system content; the system is mounted at `/os` (this feature is not supported on Debian/Kali). - `--hold 1` Reboot only into install environment, without running installer, only for SSH connect to test network connection.
- `--hold 2` Prevent reboot after installation completes, allowing SSH login to modify system content; the system is mounted at `/target` for Debian/Kali and `/os` for other distros.
> [!TIP] > [!TIP]
> When installing Debian/Kali, x86 architectures can monitor the installation progress through VNC from server provider, while ARM architectures can use the serial console.
> >
> When installing other systems, can monitor the progress through various methods (SSH, HTTP 80 port, VNC from server provider, serial console). > Can monitor the progress through various methods (SSH, HTTP 80 port, VNC from server provider, serial console).
> <br />Even if errors occur during the installation process, you can still install to Alpine via SSH by running `/trans.sh alpine` >
> Even if errors occur during the installation process, SSH is available for manual recovery.
>
> If the target system is not Debian/Kali, run `/trans.sh alpine` can automatically recover to Alpine Linux.
<details> <details>
@ -229,7 +232,7 @@ bash reinstall.sh ubuntu --installer
> >
> Data is priceless — please think twice before proceeding! > Data is priceless — please think twice before proceeding!
- Supports `raw` and `vhd` image formats (either uncompressed or compressed as `.gz`, `.xz`, `.zst`, `.tar`, `.tar.gz`, `.tar.xz`, `.tar.zst`). - Supports `raw` and fixed-size `vhd` image formats. Either uncompressed or compressed as `.gz`, `.xz`, `.zst`, `.tar`, `.tar.gz`, `.tar.xz`, `.tar.zst`.
- When deploy a Windows image, the system disk will be automatically expanded, and machines with a static IP will have their IP configured, and may take a few minutes after the first boot for the configuration to take effect. - When deploy a Windows image, the system disk will be automatically expanded, and machines with a static IP will have their IP configured, and may take a few minutes after the first boot for the configuration to take effect.
- When deploy a Linux image, will **NOT** modify any contents of the image. - When deploy a Linux image, will **NOT** modify any contents of the image.
@ -243,17 +246,22 @@ bash reinstall.sh dd --img "https://example.com/xxx.xz"
- `--rdp-port PORT` Change RDP port (DD Windows only) - `--rdp-port PORT` Change RDP port (DD Windows only)
- `--ssh-port PORT` Change SSH port (for log observation during installation) - `--ssh-port PORT` Change SSH port (for log observation during installation)
- `--web-port PORT` Change Web port (for log observation during installation) - `--web-port PORT` Change Web port (for log observation during installation)
- `--frpc-toml /path/to/frpc.toml` Add frpc for intranet tunneling (DD Windows only) - `--frpc-toml PATH` Add frpc for intranet tunneling (DD Windows only). Parameter can be local filepath or HTTP URL
- `--hold 2` Prevent reboot after the DD process finishes, allowing SSH login to modify system content. The Windows system will be mounted at `/os`, but Linux systems will **NOT** be automatically mounted. - `--hold 1` Reboot only into install environment, without running installer, only for SSH connect to test network connection.
- `--hold 2` Prevent reboot after the DD process finishes. For SSH login to modify system content. The Windows system will be mounted at `/os`, but Linux systems will **NOT** be automatically mounted.
> [!TIP] > [!TIP]
>
> Can monitor the progress through various methods (SSH, HTTP 80 port, VNC from server provider, serial console). > Can monitor the progress through various methods (SSH, HTTP 80 port, VNC from server provider, serial console).
> <br />Even if errors occur during the installation process, you can still install to Alpine via SSH by running `/trans.sh alpine` >
> Even if errors occur during the installation process, SSH is available for manual recovery.
>
> 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 (RAM 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. - You can use SSH to backup/restore disk, manually perform DD operations, partition modifications, manual Alpine installation, and other operations.
- Username `root`, Default password `123@@@` - Username `root`. The script prompts for a password. If left blank, a random one is generated.
> [!TIP] > [!TIP]
> >
@ -262,7 +270,7 @@ bash reinstall.sh dd --img "https://example.com/xxx.xz"
> If the user does not damage the original system during manual operation, rebooting will return to the original system. > If the user does not damage the original system during manual operation, rebooting will return to the original system.
```bash ```bash
bash reinstall.sh alpine --hold=1 bash reinstall.sh alpine --hold 1
``` ```
#### Optional Parameters #### Optional Parameters
@ -270,7 +278,7 @@ bash reinstall.sh alpine --hold=1
- `--password PASSWORD` Set password - `--password PASSWORD` Set password
- `--ssh-port PORT` Change SSH port - `--ssh-port PORT` Change SSH port
- `--ssh-key KEY` Set up SSH login public key, [formatted as follows](#--ssh-key). When using public key, password is empty. - `--ssh-key KEY` Set up SSH login public key, [formatted as follows](#--ssh-key). When using public key, password is empty.
- `--frpc-toml /path/to/frpc.toml` Add frpc for intranet tunneling - `--frpc-toml PATH` Add frpc for intranet tunneling. Parameter can be local filepath or HTTP URL
### Feature 4: Reboot to <img width="16" height="16" src="https://netboot.xyz/img/favicon.ico" /> netboot.xyz ### Feature 4: Reboot to <img width="16" height="16" src="https://netboot.xyz/img/favicon.ico" /> netboot.xyz
@ -298,10 +306,11 @@ bash reinstall.sh netboot.xyz
> >
> Data is priceless — please think twice before proceeding! > Data is priceless — please think twice before proceeding!
- Username `administrator`, Default password `123@@@` - Username `administrator`. The script prompts for a password. If left blank, a random one is generated.
- If remote login fails, try using the username `.\administrator`. - If remote login fails, try using the username `.\administrator`.
- The machine with a static IP will automatically configure the IP. It may take a few minutes to take effect on the first boot. - The machine with a static IP will automatically configure the IP. It may take a few minutes to take effect on the first boot.
- Supports all languages. - Supports ISO images in any language.
- Supports bypassing Windows 11 hardware requirements.
#### Supported Systems #### Supported Systems
@ -401,7 +410,6 @@ bash reinstall.sh windows \
- <https://www.microsoft.com/software-download/windows11> - <https://www.microsoft.com/software-download/windows11>
- <https://www.microsoft.com/software-download/windows11arm64> - <https://www.microsoft.com/software-download/windows11arm64>
- Evaluation - Evaluation
- <https://www.microsoft.com/evalcenter/download-windows-10-enterprise>
- <https://www.microsoft.com/evalcenter/download-windows-11-enterprise> - <https://www.microsoft.com/evalcenter/download-windows-11-enterprise>
- <https://www.microsoft.com/evalcenter/download-windows-11-iot-enterprise-ltsc-eval> - <https://www.microsoft.com/evalcenter/download-windows-11-iot-enterprise-ltsc-eval>
- <https://www.microsoft.com/evalcenter/download-windows-server-2012-r2> - <https://www.microsoft.com/evalcenter/download-windows-server-2012-r2>
@ -425,8 +433,9 @@ bash reinstall.sh windows \
- `--add-driver INF_OR_DIR` Add additional driver, specifying .inf path, or the folder contains .inf file. - `--add-driver INF_OR_DIR` Add additional driver, specifying .inf path, or the folder contains .inf file.
- The driver must be downloaded to current system first. - The driver must be downloaded to current system first.
- This parameter can be set multiple times to add different driver. - This parameter can be set multiple times to add different driver.
- `--frpc-toml /path/to/frpc.toml` Add frpc for intranet tunneling - `--frpc-toml PATH` Add frpc for intranet tunneling. Parameter can be local filepath or HTTP URL
- `--hold 2` Allow SSH connections for modifying the disk content before rebooting into the official Windows installation program, with the disk mounted at `/os`. - `--hold 1` Reboot only into install environment, without running installer, only for SSH connect to test network connection.
- `--hold 2` Allow SSH connections for modifying `boot.wim`, `install.wim` or other contents before rebooting into the official Windows installation program, with the disk mounted at `/os`.
#### The following drivers will automatic download and install as needed, without the need for manual addition #### The following drivers will automatic download and install as needed, without the need for manual addition
@ -488,20 +497,26 @@ Open File menu > Open Image File, select the iso to be installed to get the imag
> Vista (Server 2008) and 32-bit systems may lack drivers. > Vista (Server 2008) and 32-bit systems may lack drivers.
> [!WARNING] > [!WARNING]
> For EFI machines without CSM enabled, Windows 7 (Server 2008 R2) cannot be installed.
> >
> Hyper-V (Azure) requires selecting the appropriate VM generation: <https://learn.microsoft.com/windows-server/virtualization/hyper-v/plan/should-i-create-a-generation-1-or-2-virtual-machine-in-hyper-v> > For Windows 7 (Server 2008 R2) installation:
>
> 1. EFI-boot machines must enable CSM.
>
> 2. On Hyper-V (Azure), select Generation 1 VM. <https://learn.microsoft.com/windows-server/virtualization/hyper-v/plan/should-i-create-a-generation-1-or-2-virtual-machine-in-hyper-v>
> [!WARNING] > [!WARNING]
>
> In the Chinese version of Windows 10 LTSC 2021 ISO `zh-cn_windows_10_enterprise_ltsc_2021_x64_dvd_033b7312.iso`, the `wsappx` process may indefinitely consume CPU resources. > In the Chinese version of Windows 10 LTSC 2021 ISO `zh-cn_windows_10_enterprise_ltsc_2021_x64_dvd_033b7312.iso`, the `wsappx` process may indefinitely consume CPU resources.
> >
> The solution is to update the system patches or manually install the `VCLibs` library <https://www.google.com/search?q=ltsc+wsappx>. > The solution is to update the system patches or manually install the `VCLibs` library <https://www.google.com/search?q=ltsc+wsappx>.
> [!WARNING] > [!WARNING]
>
> When installing Windows ISOs released in `May 2022` or later on GCP, the system may repeatedly reboot during the Windows installation (PE) stage. You can resolve this issue using one of the following two methods: > When installing Windows ISOs released in `May 2022` or later on GCP, the system may repeatedly reboot during the Windows installation (PE) stage. You can resolve this issue using one of the following two methods:
> >
> 1. Add the `--force-boot-mode bios` parameter. The script will install Windows in `BIOS boot + MBR partition table` mode. > 1. Add the `--force-boot-mode bios` parameter. The script will install Windows in `BIOS boot + MBR partition table` mode.
> <br /> - (Optional) After installation, you can convert it to `EFI boot + GPT partition table` using the command `MBR2GPT /convert /allowFullOS`. >
> (Optional) After installation, you can convert it to `EFI boot + GPT partition table` using the command `MBR2GPT /convert /allowFullOS`.
> >
> 2. Create a custom RAW image and install it via DD. > 2. Create a custom RAW image and install it via DD.
@ -551,7 +566,7 @@ Log in to the server using Remote Desktop, open Device Manager, locate the graph
According to the Law of Bug Conservation, fixing old bugs often introduces new ones. According to the Law of Bug Conservation, fixing old bugs often introduces new ones.
If you encounter such a situation, you can try using an older version. If a new bug occurs, try using an older version to see if it works.
Go to <https://github.com/bin456789/reinstall/commits/main> and find the old versions `commit_id` on the right side. Go to <https://github.com/bin456789/reinstall/commits/main> and find the old versions `commit_id` on the right side.

View File

@ -46,7 +46,7 @@
| 系统 | 版本 | 内存 | 硬盘 | | 系统 | 版本 | 内存 | 硬盘 |
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------- | --------- | ------------ | | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------- | --------- | ------------ |
| <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.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.debian.org/favicon.ico" /> Debian | 9, 10, 11, 12, 13 | 256 MB | 1 ~ 1.5 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://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 | | <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 |
@ -54,14 +54,14 @@
| <img width="16" height="16" src="https://www.redhat.com/favicon.ico" /> RHEL &nbsp;<img width="16" height="16" src="https://almalinux.org/fav/favicon.ico" /> AlmaLinux &nbsp;<img width="16" height="16" src="https://rockylinux.org/favicon.png" /> Rocky &nbsp;<img width="16" height="16" src="https://www.oracle.com/asset/web/favicons/favicon-32.png" /> Oracle | 8, 9, 10 | 512 MB \* | 5 GB | | <img width="16" height="16" src="https://www.redhat.com/favicon.ico" /> RHEL &nbsp;<img width="16" height="16" src="https://almalinux.org/fav/favicon.ico" /> AlmaLinux &nbsp;<img width="16" height="16" src="https://rockylinux.org/favicon.png" /> Rocky &nbsp;<img width="16" height="16" src="https://www.oracle.com/asset/web/favicons/favicon-32.png" /> Oracle | 8, 9, 10 | 512 MB \* | 5 GB |
| <img width="16" height="16" src="https://opencloudos.org/qq.ico" /> OpenCloudOS | 8, 9, Stream 23 | 512 MB \* | 5 GB | | <img width="16" height="16" src="https://opencloudos.org/qq.ico" /> OpenCloudOS | 8, 9, Stream 23 | 512 MB \* | 5 GB |
| <img width="16" height="16" src="https://www.centos.org/assets/icons/favicon.svg" /> CentOS Stream | 9, 10 | 512 MB \* | 5 GB | | <img width="16" height="16" src="https://www.centos.org/assets/icons/favicon.svg" /> CentOS Stream | 9, 10 | 512 MB \* | 5 GB |
| <img width="16" height="16" src="https://fedoraproject.org/favicon.ico" /> Fedora | 41, 42 | 512 MB \* | 5 GB | | <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://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://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.05 | 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://archlinux.org/static/favicon.png" /> Arch | 滚动 | 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://www.gentoo.org/assets/img/logo/gentoo-g.png" /> Gentoo | 滚动 | 512 MB | 5 GB |
| <img width="16" height="16" src="https://aosc.io/assets/distros/aosc-os.svg" /> 安同 OS | 滚动 | 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 | 公测 | 512 MB | 8 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://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 (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) | 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 | | <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 |
@ -145,7 +145,7 @@ certutil -urlcache -f -split https://cnb.cool/bin456789/reinstall/-/git/raw/main
> >
> 数据无价,请三思而后行! > 数据无价,请三思而后行!
- 用户名 `root` 默认密码 `123@@@` - 用户名 `root`,脚本会提示输入密码,不输入则使用随机密码
- 安装最新版可不输入版本号 - 安装最新版可不输入版本号
- 最大化利用磁盘空间:不含 boot 分区Fedora 例外),不含 swap 分区 - 最大化利用磁盘空间:不含 boot 分区Fedora 例外),不含 swap 分区
- 自动根据机器类型选择不同的优化内核,例如 `Cloud``HWE` 内核 - 自动根据机器类型选择不同的优化内核,例如 `Cloud``HWE` 内核
@ -159,10 +159,11 @@ bash reinstall.sh anolis 7|8|23
almalinux 8|9|10 almalinux 8|9|10
opencloudos 8|9|23 opencloudos 8|9|23
centos 9|10 centos 9|10
fedora 41|42 fnos 1
nixos 25.05 nixos 25.11
fedora 42|43
debian 9|10|11|12|13 debian 9|10|11|12|13
alpine 3.19|3.20|3.21|3.22 alpine 3.20|3.21|3.22|3.23
opensuse 15.6|16.0|tumbleweed opensuse 15.6|16.0|tumbleweed
openeuler 20.03|22.03|24.03|25.09 openeuler 20.03|22.03|24.03|25.09
ubuntu 16.04|18.04|20.04|22.04|24.04|25.10 [--minimal] ubuntu 16.04|18.04|20.04|22.04|24.04|25.10 [--minimal]
@ -170,7 +171,6 @@ bash reinstall.sh anolis 7|8|23
arch arch
gentoo gentoo
aosc aosc
fnos
redhat --img="http://access.cdn.redhat.com/xxx.qcow2" redhat --img="http://access.cdn.redhat.com/xxx.qcow2"
``` ```
@ -180,14 +180,17 @@ bash reinstall.sh anolis 7|8|23
- `--ssh-key KEY` 设置 SSH 登录公钥,[格式如下](#--ssh-key)。当使用公钥时,密码为空 - `--ssh-key KEY` 设置 SSH 登录公钥,[格式如下](#--ssh-key)。当使用公钥时,密码为空
- `--ssh-port PORT` 修改 SSH 端口(安装期间观察日志用,也作用于新系统) - `--ssh-port PORT` 修改 SSH 端口(安装期间观察日志用,也作用于新系统)
- `--web-port PORT` 修改 Web 端口(安装期间观察日志用) - `--web-port PORT` 修改 Web 端口(安装期间观察日志用)
- `--frpc-toml /path/to/frpc.toml` 添加 frpc 内网穿透 - `--frpc-toml PATH` 添加 frpc 内网穿透,参数填本地路径或 HTTP 链接
- `--hold 2` 安装结束后不重启,此时可以 SSH 登录修改系统内容,系统挂载在 `/os` (此功能不支持 Debian/Kali) - `--hold 1` 仅重启到安装环境,不运行安装,用于 SSH 登录验证网络连通性
- `--hold 2` 安装结束后不重启,用于 SSH 登录修改系统内容Debian/Kali 会挂载在 `/target`,其它系统会挂载在 `/os`
> [!TIP] > [!TIP]
> 安装 Debian/Kali 时x86 可通过商家后台 VNC 查看安装进度ARM 可通过串行控制台查看安装进度。
> >
> 安装其它系统时,可通过多种方式SSH、HTTP 80 端口、商家后台 VNC、串行控制台查看安装进度。 > 可通过多种方式SSH、HTTP 80 端口、商家后台 VNC、串行控制台查看安装进度。
> <br />即使安装过程出错,也能通过 SSH 运行 `/trans.sh alpine` 安装到 Alpine。 >
> 即使安装过程出错,也能连接 SSH 手动救砖。
>
> 目标系统非 Debian/Kali 时,可以运行 `/trans.sh alpine` 自动救砖成 Alpine 系统。
<details> <details>
@ -229,7 +232,7 @@ bash reinstall.sh ubuntu --installer
> >
> 数据无价,请三思而后行! > 数据无价,请三思而后行!
- 支持 `raw` `vhd` 格式的镜像未压缩或者压缩成 `.gz` `.xz` `.zst` `.tar` `.tar.gz` `.tar.xz` `.tar.zst` - 支持 `raw` 和固定大小的 `vhd` 镜像未压缩或者压缩成 `.gz` `.xz` `.zst` `.tar` `.tar.gz` `.tar.xz` `.tar.zst`
- DD Windows 镜像时,会自动扩展系统盘,静态 IP 的机器会配置好 IP可能首次开机几分钟后才生效 - DD Windows 镜像时,会自动扩展系统盘,静态 IP 的机器会配置好 IP可能首次开机几分钟后才生效
- DD Linux 镜像时,**不会**修改镜像的任何内容 - DD Linux 镜像时,**不会**修改镜像的任何内容
@ -243,17 +246,22 @@ bash reinstall.sh dd --img "https://example.com/xxx.xz"
- `--rdp-port PORT` 修改 RDP 端口 (仅限 DD Windows) - `--rdp-port PORT` 修改 RDP 端口 (仅限 DD Windows)
- `--ssh-port PORT` 修改 SSH 端口(安装期间观察日志用) - `--ssh-port PORT` 修改 SSH 端口(安装期间观察日志用)
- `--web-port PORT` 修改 Web 端口(安装期间观察日志用) - `--web-port PORT` 修改 Web 端口(安装期间观察日志用)
- `--frpc-toml /path/to/frpc.toml` 添加 frpc 内网穿透(仅限 DD Windows - `--frpc-toml PATH` 添加 frpc 内网穿透(仅限 DD Windows,参数填本地路径或 HTTP 链接
- `--hold 2` DD 结束后不重启,此时可以 SSH 登录修改系统内容Windows 系统会挂载在 `/os`Linux 系统**不会**自动挂载 - `--hold 1` 仅重启到安装环境,不运行安装,用于 SSH 登录验证网络连通性
- `--hold 2` DD 结束后不重启,用于 SSH 登录修改系统内容Windows 系统会挂载在 `/os`Linux 系统**不会**自动挂载
> [!TIP] > [!TIP]
>
> 可通过多种方式SSH、HTTP 80 端口、商家后台 VNC、串行控制台查看安装进度。 > 可通过多种方式SSH、HTTP 80 端口、商家后台 VNC、串行控制台查看安装进度。
> <br />即使安装过程出错,也能通过 SSH 运行 `/trans.sh alpine` 安装到 Alpine。 >
> 即使安装过程出错,也能连接 SSH 手动救砖
>
> 也可以运行 `/trans.sh alpine` 自动救砖成 Alpine 系统。
### 功能 3: 重启到 <img width="16" height="16" src="https://www.alpinelinux.org/alpine-logo.ico" /> Alpine Live OS内存系统 ### 功能 3: 重启到 <img width="16" height="16" src="https://www.alpinelinux.org/alpine-logo.ico" /> Alpine Live OS内存系统
- 可用 ssh 连接,进行备份/恢复硬盘、手动 DD、修改分区、手动安装 Alpine 等操作 - 可用 ssh 连接,进行备份/恢复硬盘、手动 DD、修改分区、手动安装 Alpine 等操作
- 用户名 `root` 默认密码 `123@@@` - 用户名 `root`,脚本会提示输入密码,不输入则使用随机密码
> [!TIP] > [!TIP]
> >
@ -262,7 +270,7 @@ bash reinstall.sh dd --img "https://example.com/xxx.xz"
> 如果用户手动操作没有破坏原系统,再次重启将回到原系统 > 如果用户手动操作没有破坏原系统,再次重启将回到原系统
```bash ```bash
bash reinstall.sh alpine --hold=1 bash reinstall.sh alpine --hold 1
``` ```
#### 可选参数 #### 可选参数
@ -270,7 +278,7 @@ bash reinstall.sh alpine --hold=1
- `--password PASSWORD` 设置密码 - `--password PASSWORD` 设置密码
- `--ssh-port PORT` 修改 SSH 端口 - `--ssh-port PORT` 修改 SSH 端口
- `--ssh-key KEY` 设置 SSH 登录公钥,[格式如下](#--ssh-key)。当使用公钥时,密码为空 - `--ssh-key KEY` 设置 SSH 登录公钥,[格式如下](#--ssh-key)。当使用公钥时,密码为空
- `--frpc-toml /path/to/frpc.toml` 添加 frpc 内网穿透 - `--frpc-toml PATH` 添加 frpc 内网穿透,参数填本地路径或 HTTP 链接
### 功能 4: 重启到 <img width="16" height="16" src="https://netboot.xyz/img/favicon.ico" /> netboot.xyz ### 功能 4: 重启到 <img width="16" height="16" src="https://netboot.xyz/img/favicon.ico" /> netboot.xyz
@ -298,10 +306,11 @@ bash reinstall.sh netboot.xyz
> >
> 数据无价,请三思而后行! > 数据无价,请三思而后行!
- 用户名 `administrator` 默认密码 `123@@@` - 用户名 `administrator`,脚本会提示输入密码,不输入则使用随机密码
- 如果远程登录失败,可以尝试使用用户名 `.\administrator` - 如果远程登录失败,可以尝试使用用户名 `.\administrator`
- 静态机器会自动配置好 IP可能首次开机几分钟后才生效 - 静态机器会自动配置好 IP可能首次开机几分钟后才生效
- 支持所有语言 - 支持任意语言的 ISO
- 支持绕过 Windows 11 硬件限制
#### 支持的系统 #### 支持的系统
@ -401,7 +410,6 @@ bash reinstall.sh windows \
- <https://www.microsoft.com/software-download/windows11> - <https://www.microsoft.com/software-download/windows11>
- <https://www.microsoft.com/software-download/windows11arm64> - <https://www.microsoft.com/software-download/windows11arm64>
- 评估版 - 评估版
- <https://www.microsoft.com/evalcenter/download-windows-10-enterprise>
- <https://www.microsoft.com/evalcenter/download-windows-11-enterprise> - <https://www.microsoft.com/evalcenter/download-windows-11-enterprise>
- <https://www.microsoft.com/evalcenter/download-windows-11-iot-enterprise-ltsc-eval> - <https://www.microsoft.com/evalcenter/download-windows-11-iot-enterprise-ltsc-eval>
- <https://www.microsoft.com/evalcenter/download-windows-server-2012-r2> - <https://www.microsoft.com/evalcenter/download-windows-server-2012-r2>
@ -425,8 +433,9 @@ bash reinstall.sh windows \
- `--add-driver INF_OR_DIR` 添加额外驱动,填写 .inf 路径,或者 .inf 所在的文件夹 - `--add-driver INF_OR_DIR` 添加额外驱动,填写 .inf 路径,或者 .inf 所在的文件夹
- 需先下载驱动到当前系统 - 需先下载驱动到当前系统
- 可多次设置该参数以添加不同的驱动 - 可多次设置该参数以添加不同的驱动
- `--frpc-toml /path/to/frpc.toml` 添加 frpc 内网穿透 - `--frpc-toml PATH` 添加 frpc 内网穿透,参数填本地路径或 HTTP 链接
- `--hold 2` 在进入 Windows 官方安装程序之前,可以 SSH 登录修改硬盘内容,硬盘挂载在 `/os` - `--hold 1` 仅重启到安装环境,不运行安装,用于 SSH 登录验证网络连通性
- `--hold 2` 用于在进入 Windows 官方安装程序之前SSH 登录修改 `boot.wim``install.wim` 或者其它内容,硬盘挂载在 `/os`
#### 以下驱动会自动按需下载安装,无需手动添加 #### 以下驱动会自动按需下载安装,无需手动添加
@ -488,20 +497,26 @@ Windows Server 2025 SERVERDATACENTER
> Vista (Server 2008) 和 32 位系统可能会缺少驱动 > Vista (Server 2008) 和 32 位系统可能会缺少驱动
> [!WARNING] > [!WARNING]
> 未开启 CSM 的 EFI 机器,无法安装 Windows 7 (Server 2008 R2)
> >
> Hyper-V (Azure) 需选择合适的虚拟机代系 <https://learn.microsoft.com/windows-server/virtualization/hyper-v/plan/should-i-create-a-generation-1-or-2-virtual-machine-in-hyper-v> > 安装 Windows 7 (Server 2008 R2) 时
>
> 1. EFI 引导的机器要开启 CSM
>
> 2. Hyper-V (Azure) 需选择第 1 代虚拟机 <https://learn.microsoft.com/windows-server/virtualization/hyper-v/plan/should-i-create-a-generation-1-or-2-virtual-machine-in-hyper-v>
> [!WARNING] > [!WARNING]
>
> Windows 10 LTSC 2021 中文版镜像 `zh-cn_windows_10_enterprise_ltsc_2021_x64_dvd_033b7312.iso` 的 `wsappx` 进程会长期占用 CPU > Windows 10 LTSC 2021 中文版镜像 `zh-cn_windows_10_enterprise_ltsc_2021_x64_dvd_033b7312.iso` 的 `wsappx` 进程会长期占用 CPU
> >
> 解决方法是更新系统补丁,或者手动安装 `VCLibs` 库 <https://www.google.com/search?q=ltsc+wsappx> > 解决方法是更新系统补丁,或者手动安装 `VCLibs` 库 <https://www.google.com/search?q=ltsc+wsappx>
> [!WARNING] > [!WARNING]
>
> 在 GCP 上安装 `2022年5月` 和之后发布的 Windows ISO在引导 Windows 安装界面 (PE) 时会不断反复重启。解决方法如下,二选一 > 在 GCP 上安装 `2022年5月` 和之后发布的 Windows ISO在引导 Windows 安装界面 (PE) 时会不断反复重启。解决方法如下,二选一
> >
> 1. 添加 `--force-boot-mode bios` 参数,脚本将以 `BIOS 引导 + MBR 分区表` 方式安装 Windows > 1. 添加 `--force-boot-mode bios` 参数,脚本将以 `BIOS 引导 + MBR 分区表` 方式安装 Windows
> <br /> - (可选) 安装完成后用 `MBR2GPT /convert /allowFullOS` 命令转为 `EFI 引导 + GPT 分区表` >
> (可选) 安装完成后用 `MBR2GPT /convert /allowFullOS` 命令转为 `EFI 引导 + GPT 分区表`
> >
> 2. 自制 RAW 镜像并通过 DD 安装 > 2. 自制 RAW 镜像并通过 DD 安装
@ -551,7 +566,7 @@ Windows Server 2025 SERVERDATACENTER
根据 Bug 守恒定律,修复旧 Bug 的同时会引入新的 Bug 根据 Bug 守恒定律,修复旧 Bug 的同时会引入新的 Bug
如果遇到这种情况,可以尝试使用旧版本 如果遇到新的 Bug可以试下旧版本是否正常
<https://github.com/bin456789/reinstall/commits/main> 右侧找到旧版本的 `commit_id` <https://github.com/bin456789/reinstall/commits/main> 右侧找到旧版本的 `commit_id`

View File

@ -6,10 +6,10 @@
# 需要留意 kali initrd 自带的 /preseed.cfg # 需要留意 kali initrd 自带的 /preseed.cfg
# 下面这行语句无效,因为本行后面有反斜杠,前面有空格(安装器认为不算注释)\ # 下面这行语句无效,因为本行后面有反斜杠,前面有空格(安装器认为不算注释)\
d-i debian-installer/locale string en_US d-i debian-installer/locale string en_US.UTF-8
# B.4.1. 本地化 # B.4.1. 本地化
d-i debian-installer/locale string en_US d-i debian-installer/locale string en_US.UTF-8
d-i keyboard-configuration/xkb-keymap select us d-i keyboard-configuration/xkb-keymap select us
# B.4.2. 网络设置 # B.4.2. 网络设置
@ -25,10 +25,10 @@ d-i mirror/country string manual
# B.4.5. 帐号设置 # B.4.5. 帐号设置
d-i passwd/make-user boolean false d-i passwd/make-user boolean false
# 单纯为了跳过设置,实际上是在 partman/early_command 里设置密码preseed/early_command 无法设置密码
# 注意如果用 ssh key 后面还要删除密码 # 注意如果用 ssh key 后面还要删除密码
d-i passwd/root-password password '' # d-i passwd/root-password password ''
d-i passwd/root-password-again password '' # d-i passwd/root-password-again password ''
# d-i passwd/root-password-crypted password ''
# kali 需要下面这行,否则会提示输入用户名 # kali 需要下面这行,否则会提示输入用户名
d-i passwd/root-login boolean true d-i passwd/root-login boolean true
@ -63,6 +63,9 @@ d-i partman-efi/non_efi_system boolean true
# 选择 true 就一直死循环 # 选择 true 就一直死循环
d-i partman-basicfilesystems/no_swap boolean false d-i partman-basicfilesystems/no_swap boolean false
# 分区大小计算
# https://salsa.debian.org/installer-team/partman-base/-/blob/master/lib/base.sh
# 最小值 膨胀权重 最大值 # 最小值 膨胀权重 最大值
# https://salsa.debian.org/installer-team/partman-auto/-/blob/master/recipes/atomic?ref_type=heads # https://salsa.debian.org/installer-team/partman-auto/-/blob/master/recipes/atomic?ref_type=heads
# https://salsa.debian.org/installer-team/partman-auto/-/blob/master/recipes-amd64-efi/atomic?ref_type=heads # https://salsa.debian.org/installer-team/partman-auto/-/blob/master/recipes-amd64-efi/atomic?ref_type=heads
@ -73,6 +76,7 @@ d-i partman-auto/expert_recipe_efi string efi :: \
1 1 -1 $default_filesystem \ 1 1 -1 $default_filesystem \
method{ format } format{ } use_filesystem{ } $default_filesystem{ } mountpoint{ / } . method{ format } format{ } use_filesystem{ } $default_filesystem{ } mountpoint{ / } .
# 大于 2T 会自动用 gpt
# shellcheck disable=SC1083,SC2086,SC2154 # shellcheck disable=SC1083,SC2086,SC2154
d-i partman-auto/expert_recipe_bios string bios :: \ d-i partman-auto/expert_recipe_bios string bios :: \
1 1 1 free \ 1 1 1 free \
@ -99,26 +103,127 @@ d-i pkgsel/upgrade select none
d-i grub-installer/force-efi-extra-removable boolean true d-i grub-installer/force-efi-extra-removable boolean true
# B.4.12. 完成安装 # B.4.12. 完成安装
d-i finish-install/reboot_in_progress note # 由下面的 hold 2 设置
# d-i finish-install/reboot_in_progress note
# B.4.13. 预置其他的软件包 # B.4.13. 预置其他的软件包
# 其他设置 # 其他设置
# d-i anna/standard_modules boolean false # d-i anna/standard_modules boolean false
# d-i anna/choose_modules string network-console # d-i anna/choose_modules string network-console
# d-i network-console/password password 123@@@ # d-i network-console/password password ''
# d-i network-console/password-again password 123@@@ # d-i network-console/password-again password ''
# B.5.1. 安装过程中运行用户命令 # B.5.1. 安装过程中运行用户命令
# 注意所有命令都会合并成一行命令 # 注意所有命令都会合并成一行命令
# 最后的 true; \ 没什么用,只是让 vscode 代码高亮不报错误 # 最后的 true; \ 没什么用,只是让 vscode 代码高亮不报错误
# debian 11+ 才有 websocketd
# 有 /cdrom/simple-cdd 才安装 simple-cdd-profiles # 有 /cdrom/simple-cdd 才安装 simple-cdd-profiles
# 不然安装时 control 脚本会报错: # 不然安装时 control 脚本会报错:
# Loading simple-cdd-profiles failed for unknown reasons # Loading simple-cdd-profiles failed for unknown reasons
# 未下载的组件,无法用 debconf-set需要用 debconf-set-selections
# https://salsa.debian.org/installer-team/network-console/-/blob/master/debian/network-console.postinst?ref_type=heads
# https://salsa.debian.org/installer-team/user-setup/-/blob/master/user-setup-apply?ref_type=heads
# 此时还没有配置源anna-install 会在配置完源后再安装
d-i preseed/early_command string true; \ d-i preseed/early_command string true; \
if [ -d /cdrom/simple-cdd ]; then anna-install simple-cdd-profiles; fi for str in $(grep -wo "extra_[^ ]*" /proc/cmdline | sed 's/^extra_//'); do eval "$str"; done; \
di(){ \
echo "d-i $*" >/tmp/selections.cfg; \
echo "d-i $*" >>/tmp/selections.cfg.all; \
debconf-set-selections /tmp/selections.cfg; \
rm -f /tmp/selections.cfg; \
}; \
run_as_service_with_screen() { \
if ! [ -f /etc/screenrc.bak ]; then \
cp /etc/screenrc /etc/screenrc.bak; \
fi; \
true >/etc/screenrc; \
screen sh -c 'while true; do pidof ${1##*/} || "$@"; sleep 5; done' _ "$@"; \
cp -f /etc/screenrc.bak /etc/screenrc; \
}; \
if [ "$hold" = 1 ]; then \
di auto-install/enable boolean false; \
di debconf/priority select low; \
di partman/early_command string; \
else \
{ \
echo 'Reinstalling...'; \
echo 'Option 1. View logs:'; \
echo ' tail -fn+1 /var/log/syslog'; \
echo 'Option 2. Attach to the installer:'; \
echo ' TERM=screen screen -xp1'; \
} >>/etc/motd; \
mem=$(grep ^MemTotal: /proc/meminfo | { read -r _ y _; echo "$((y / 1024))"; }); \
if command -v websocketd && [ "$mem" -ge 400 ]; then \
for _ in {1..10}; do \
if wget "$confhome/logviewer.html" -O /tmp/index.html; then \
break; \
fi; \
sleep 5; \
done; \
if [ -z "$web_port" ]; then \
web_port=80; \
fi; \
run_as_service_with_screen websocketd --port 80 --loglevel=fatal --staticdir=/tmp \
sh -c "tail -fn+0 /var/log/syslog | tr '\r' '\n' | grep -Fiv -e password -e token" ; \
fi; \
fi; \
if ! [ "$hold" = 2 ]; then \
di finish-install/reboot_in_progress note; \
fi; \
if [ -s /configs/ssh_keys ]; then \
di passwd/root-password-crypted password "''"; \
else \
di passwd/root-password-crypted password "$(cat /configs/password-linux-sha512)"; \
fi; \
mkdir -p /etc/ssh; \
true >/etc/ssh/sshd_config; \
if [ -s /configs/ssh_keys ]; then \
(umask 077; mkdir -p /.ssh; cat /configs/ssh_keys >/.ssh/authorized_keys); \
else \
echo "PermitRootLogin yes" >>/etc/ssh/sshd_config; \
fi; \
if [ -n "$ssh_port" ] && ! [ "$ssh_port" = 22 ]; then \
echo "Port $ssh_port" >>/etc/ssh/sshd_config; \
fi; \
grep -qs ^root: /etc/shadow || echo "root:$(cat /configs/password-linux-sha512):1:0:99999:7:::" >>/etc/shadow; \
grep -qs ^nogroup: /etc/group || echo "nogroup:*:65534:" >>/etc/group; \
grep -qs ^sshd: /etc/passwd || echo "sshd:*:100:65534::/run/sshd:/bin/false" >>/etc/passwd; \
mkdir -p /run/sshd; \
chmod 0755 /run/sshd; \
ssh-keygen -A; \
run_as_service_with_screen /usr/sbin/sshd -D; \
if [ -s /configs/frpc.toml ]; then \
url=$(sh /get-frpc-url.sh linux); \
mkdir -p /usr/local/bin; \
mkdir -p /usr/local/etc/frpc; \
for _ in {1..10}; do \
if wget -O- "$url" | tar xz "*/frpc" -O >/usr/local/bin/frpc; then \
break; \
fi; \
sleep 5; \
done; \
chmod a+x /usr/local/bin/frpc; \
cp /configs/frpc.toml /usr/local/etc/frpc/; \
run_as_service_with_screen /usr/local/bin/frpc -c /usr/local/etc/frpc/frpc.toml; \
fi; \
if [ -d /cdrom/simple-cdd ]; then \
anna-install simple-cdd-profiles; \
fi
# debian 11 initrd 没有 xargs awk # debian 11 initrd 没有 xargs awk
# debian 12 initrd 没有 xargs # debian 12 initrd 没有 xargs
@ -132,10 +237,11 @@ d-i partman/early_command string true; \
true >$postinst; \ true >$postinst; \
swapfile=/target/swapfile; \ swapfile=/target/swapfile; \
mem=$(grep ^MemTotal: /proc/meminfo | { read -r _ y _; echo "$y"; }); \ mem=$(grep ^MemTotal: /proc/meminfo | { read -r _ y _; echo "$((y / 1024))"; }); \
mem=$((mem / 1024)); \
swap_size=$((512 - mem)); \ swap_size=$((512 - mem)); \
[ $swap_size -gt 0 ] && echo "fallocate -l ${swap_size}M $swapfile; mkswap $swapfile; swapon $swapfile" >>$postinst; \ if [ $swap_size -gt 0 ]; then \
echo "fallocate -l ${swap_size}M $swapfile; mkswap $swapfile; swapon $swapfile" >>$postinst; \
fi; \
echo "swapoff -a; rm -f $swapfile" >/usr/lib/finish-install.d/95swapoff; \ echo "swapoff -a; rm -f $swapfile" >/usr/lib/finish-install.d/95swapoff; \
chmod a+x /usr/lib/finish-install.d/95swapoff; \ chmod a+x /usr/lib/finish-install.d/95swapoff; \
@ -152,12 +258,15 @@ d-i partman/early_command string true; \
eths=$(cd /dev/netconf/ && ls); \ eths=$(cd /dev/netconf/ && ls); \
sh /can_use_cloud_kernel.sh "$xda" $eths || debconf-set base-installer/kernel/image "$(debconf-get base-installer/kernel/image | sed 's/-cloud//')"; \ if ! sh /can_use_cloud_kernel.sh "$xda" $eths; then \
debconf-set base-installer/kernel/image "$(debconf-get base-installer/kernel/image | sed 's/-cloud//')"; \
fi; \
[ -d /sys/firmware/efi ] && debconf-set partman-auto/expert_recipe "$(debconf-get partman-auto/expert_recipe_efi)"; \ if [ -d /sys/firmware/efi ]; then \
[ -d /sys/firmware/efi ] || debconf-set partman-auto/expert_recipe "$(debconf-get partman-auto/expert_recipe_bios)"; \ debconf-set partman-auto/expert_recipe "$(debconf-get partman-auto/expert_recipe_efi)"; \
else \
debconf-set passwd/root-password-crypted "$(cat /configs/password-linux-sha512)"; \ debconf-set partman-auto/expert_recipe "$(debconf-get partman-auto/expert_recipe_bios)"; \
fi; \
true >/bin/os-prober true >/bin/os-prober
@ -188,17 +297,11 @@ d-i preseed/late_command string true; \
fi; \ fi; \
if [ -s /configs/frpc.toml ]; then \ if [ -s /configs/frpc.toml ]; then \
url=$(sh /get-frpc-url.sh linux); \
basename=$(echo "$url" | sed 's,.*/,,' | sed 's,\.tar\.gz,,'); \
mkdir -p /target/usr/local/bin; \ mkdir -p /target/usr/local/bin; \
mkdir -p /target/usr/local/etc/frpc; \ mkdir -p /target/usr/local/etc/frpc; \
for i in {1..5}; do \ cp /usr/local/bin/frpc /target/usr/local/bin/; \
wget -O /target/frpc.tar.gz "$url" && break; \ cp /usr/local/etc/frpc/frpc.toml /target/usr/local/etc/frpc/; \
done; \
tar xzf /target/frpc.tar.gz "$basename/frpc" -O >/target/usr/local/bin/frpc; \
rm -f /target/frpc.tar.gzx; \
chmod a+x /target/usr/local/bin/frpc; \ chmod a+x /target/usr/local/bin/frpc; \
cp /configs/frpc.toml /target/usr/local/etc/frpc/; \
cp /frpc.service /target/etc/systemd/system/; \ cp /frpc.service /target/etc/systemd/system/; \
in-target systemctl enable frpc; \ in-target systemctl enable frpc; \
fi; \ fi; \

View File

@ -48,21 +48,40 @@ retry() {
# 用 systemd-analyze plot >a.svg 发现 sys-subsystem-net-devices-enp3s0.device 也是出现在 NetworkManager 之后 # 用 systemd-analyze plot >a.svg 发现 sys-subsystem-net-devices-enp3s0.device 也是出现在 NetworkManager 之后
# 因此需要等待网卡出现 # 因此需要等待网卡出现
get_ethx_by_mac() { get_ethx_by_mac() {
mac=$(echo "$1" | to_lower) retry 10 _get_ethx_by_mac "$@"
retry 10 _get_ethx_by_mac "$mac"
} }
_get_ethx_by_mac() { _get_ethx_by_mac() {
mac=$(echo "$1" | to_lower)
flag=$2
if [ -z "$flag" ]; then
flag=master
fi
if true; then if true; then
if [ "$flag" = master ]; then
# master
# 过滤 azure vf (带 master ethx) # 过滤 azure vf (带 master ethx)
ip -o link | grep -i "$mac" | grep -v master | awk '{print $2}' | cut -d: -f1 | grep . ip -o link | grep -i "$mac" | grep -v master | awk '{print $2}' | cut -d: -f1 | grep .
return else
# slave
# 带 master ethx
ip -o link | grep -i "$mac" | grep -w master | awk '{print $2}' | cut -d: -f1 | grep .
fi
else else
for i in $(cd /sys/class/net && echo *); do for i in $(cd /sys/class/net && echo *); do
if [ "$(cat "/sys/class/net/$i/address")" = "$mac" ]; then 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" echo "$i"
return return
fi fi
fi
done done
return 1 return 1
fi fi
@ -138,6 +157,23 @@ fix_network_manager() {
# 更改文件名 # 更改文件名
mv "$file" "$proper_file" 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 done
} }

View File

@ -1,6 +1,6 @@
serverAddr = "YOUR_FRP_SERVER_IP" serverAddr = "11.22.33.44"
serverPort = 7000 serverPort = 7000
auth.token = "YOUR_FRP_TOKEN" auth.token = "123456"
[[proxies]] [[proxies]]
name = "ssh" name = "ssh"

View File

@ -10,7 +10,7 @@ is_in_china() {
} }
is_ipv6_only() { is_ipv6_only() {
! grep -q 1 /dev/netconf/eth*/ipv4_has_internet ! grep -q 1 /dev/netconf/*/ipv4_has_internet
} }
get_frpc_url() { get_frpc_url() {

View File

@ -240,11 +240,17 @@ test_connect() {
test_internet() { test_internet() {
for i in $(seq 5); do for i in $(seq 5); do
echo "Testing Internet Connection. Test $i... " echo "Testing Internet Connection. Test $i... "
if is_need_test_ipv4 && { local current_ipv4_addr; current_ipv4_addr="$(get_first_ipv4_addr | remove_netmask)"; test_connect "$current_ipv4_addr" "$ipv4_dns1" >/dev/null 2>&1 || test_connect "$current_ipv4_addr" "$ipv4_dns2" >/dev/null 2>&1; }; then if is_need_test_ipv4 &&
current_ipv4_addr="$(get_first_ipv4_addr | remove_netmask)" &&
{ test_connect "$current_ipv4_addr" "$ipv4_dns1" ||
test_connect "$current_ipv4_addr" "$ipv4_dns2"; } >/dev/null 2>&1; then
echo "IPv4 has internet." echo "IPv4 has internet."
ipv4_has_internet=true ipv4_has_internet=true
fi fi
if is_need_test_ipv6 && { local current_ipv6_addr; current_ipv6_addr="$(get_first_ipv6_addr | remove_netmask)"; test_connect "$current_ipv6_addr" "$ipv6_dns1" >/dev/null 2>&1 || test_connect "$current_ipv6_addr" "$ipv6_dns2" >/dev/null 2>&1; }; then if is_need_test_ipv6 &&
current_ipv6_addr="$(get_first_ipv6_addr | remove_netmask)" &&
{ test_connect "$current_ipv6_addr" "$ipv6_dns1" ||
test_connect "$current_ipv6_addr" "$ipv6_dns2"; } >/dev/null 2>&1; then
echo "IPv6 has internet." echo "IPv6 has internet."
ipv6_has_internet=true ipv6_has_internet=true
fi fi
@ -339,8 +345,9 @@ EOF
db_progress INFO netcfg/link_detect_progress db_progress INFO netcfg/link_detect_progress
else else
# alpine # alpine
# h3c 移动云电脑使用 udhcpc 会重复提示 sending select无法获得 ipv6,因此使用 dhcpcd # h3c 移动云电脑使用 udhcpc 会重复提示 sending select无法获得 ipv6
method=dhcpcd # dhcpcd 会配置租约时间,过期会移除 IP但我们的没有在后台运行 dhcpcd ,因此用 udhcpc
method=udhcpc
case "$method" in case "$method" in
udhcpc) udhcpc)

View File

@ -66,6 +66,12 @@
const scrollToBottomButton = document.getElementById('scroll-to-bottom'); const scrollToBottomButton = document.getElementById('scroll-to-bottom');
let shouldScrollToBottom = true; let shouldScrollToBottom = true;
// 缓冲区相关
let messageBuffer = [];
let flushScheduled = false;
const BUFFER_FLUSH_INTERVAL = 100; // 毫秒
const BUFFER_MAX_SIZE = 50; // 最大缓冲消息数
scrollToBottomButton.addEventListener('click', () => { scrollToBottomButton.addEventListener('click', () => {
logContainer.scrollTop = logContainer.scrollHeight; logContainer.scrollTop = logContainer.scrollHeight;
}); });
@ -81,30 +87,71 @@
shouldScrollToBottom = isAtBottom; shouldScrollToBottom = isAtBottom;
}); });
var ws = new ReconnectingWebSocket('ws://' + location.host + '/'); // 刷新缓冲区到 DOM
ws.onopen = function () { function flushBuffer() {
logContainer.textContent += '\nWebSocket Connected.'; if (messageBuffer.length === 0) {
}; flushScheduled = false;
ws.onclose = function () { return;
logContainer.textContent += '\nWebSocket Disconnected.'; }
};
ws.onmessage = function (event) { // 批量更新文本内容
logContainer.textContent += '\n' + event.data; const batchText = messageBuffer.join('\n');
logContainer.textContent += '\n' + batchText;
// 检查状态变化优先级error > done > start
if (batchText.includes('***** ERROR *****')) {
document.body.className = 'error';
} else if (batchText.includes('***** DONE *****')) {
document.body.className = 'done';
} else if (batchText.includes('***** START TRANS *****')) {
document.body.className = '';
}
// 自动滚动
if (shouldScrollToBottom) { if (shouldScrollToBottom) {
logContainer.scrollTop = logContainer.scrollHeight; logContainer.scrollTop = logContainer.scrollHeight;
} }
// 开始/重新开始
if (event.data.includes('***** START TRANS *****')) { // 清空缓冲区
document.body.className = '' messageBuffer = [];
flushScheduled = false;
} }
// 错误
else if (event.data.includes('***** ERROR *****')) { // 调度刷新
document.body.className = 'error' function scheduleFlush() {
if (!flushScheduled) {
flushScheduled = true;
requestAnimationFrame(() => {
setTimeout(flushBuffer, BUFFER_FLUSH_INTERVAL);
});
} }
// 完成
else if (event.data.includes('***** DONE *****')) {
document.body.className = 'done'
} }
// 添加消息到缓冲区
function bufferMessage(message) {
messageBuffer.push(message);
// 如果缓冲区满了,立即刷新
if (messageBuffer.length >= BUFFER_MAX_SIZE) {
if (flushScheduled) {
// 取消之前的调度,立即刷新
flushScheduled = false;
}
flushBuffer();
} else {
scheduleFlush();
}
}
var ws = new ReconnectingWebSocket('ws://' + location.host + '/');
ws.onopen = function () {
bufferMessage('WebSocket Connected.');
};
ws.onclose = function () {
bufferMessage('WebSocket Disconnected.');
};
ws.onmessage = function (event) {
bufferMessage(event.data);
}; };
</script> </script>
</body> </body>

View File

@ -7,11 +7,8 @@ confhome=https://raw.githubusercontent.com/bin456789/reinstall/main
confhome_cn=https://cnb.cool/bin456789/reinstall/-/git/raw/main confhome_cn=https://cnb.cool/bin456789/reinstall/-/git/raw/main
# confhome_cn=https://www.ghproxy.cc/https://raw.githubusercontent.com/bin456789/reinstall/main # confhome_cn=https://www.ghproxy.cc/https://raw.githubusercontent.com/bin456789/reinstall/main
# 默认密码
DEFAULT_PASSWORD=123@@@
# 用于判断 reinstall.sh 和 trans.sh 是否兼容 # 用于判断 reinstall.sh 和 trans.sh 是否兼容
SCRIPT_VERSION=4BACD833-A585-23BA-6CBB-9AA4E08E0003 SCRIPT_VERSION=4BACD833-A585-23BA-6CBB-9AA4E08E0004
# 记录要用到的 windows 程序,运行时输出删除 \r # 记录要用到的 windows 程序,运行时输出删除 \r
WINDOWS_EXES='cmd powershell wmic reg diskpart netsh bcdedit mountvol' WINDOWS_EXES='cmd powershell wmic reg diskpart netsh bcdedit mountvol'
@ -25,6 +22,22 @@ export LC_ALL=C
# 不要漏了最后的 $PATH否则会找不到 windows 系统程序例如 diskpart # 不要漏了最后的 $PATH否则会找不到 windows 系统程序例如 diskpart
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$PATH 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 的行 # 记录日志,过滤含有 password 的行
exec > >(tee >(grep -iv password >>/reinstall.log)) 2>&1 exec > >(tee >(grep -iv password >>/reinstall.log)) 2>&1
THIS_SCRIPT=$(readlink -f "$0") THIS_SCRIPT=$(readlink -f "$0")
@ -51,10 +64,11 @@ Usage: $reinstall_____ anolis 7|8|23
oracle 8|9|10 oracle 8|9|10
almalinux 8|9|10 almalinux 8|9|10
centos 9|10 centos 9|10
fedora 41|42 fnos 1
nixos 25.05 nixos 25.11
fedora 42|43
debian 9|10|11|12|13 debian 9|10|11|12|13
alpine 3.19|3.20|3.21|3.22 alpine 3.20|3.21|3.22|3.23
opensuse 15.6|16.0|tumbleweed opensuse 15.6|16.0|tumbleweed
openeuler 20.03|22.03|24.03|25.09 openeuler 20.03|22.03|24.03|25.09
ubuntu 16.04|18.04|20.04|22.04|24.04|25.10 [--minimal] ubuntu 16.04|18.04|20.04|22.04|24.04|25.10 [--minimal]
@ -62,7 +76,6 @@ Usage: $reinstall_____ anolis 7|8|23
arch arch
gentoo gentoo
aosc aosc
fnos
redhat --img="http://access.cdn.redhat.com/xxx.qcow2" 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) 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 windows --image-name="windows xxx yyy" --lang=xx-yy
@ -74,7 +87,7 @@ Usage: $reinstall_____ anolis 7|8|23
[--ssh-key KEY] [--ssh-key KEY]
[--ssh-port PORT] [--ssh-port PORT]
[--web-port PORT] [--web-port PORT]
[--frpc-toml TOML] [--frpc-toml PATH]
For Windows Only: For Windows Only:
[--allow-ping] [--allow-ping]
@ -126,14 +139,35 @@ error_and_exit() {
exit 1 exit 1
} }
show_dd_password_tips() {
warn false "
This password is only used for SSH access to view logs during the installation.
Password of the image will NOT modify.
密码仅用于安装过程中通过 SSH 查看日志。
镜像的密码不会被修改。
"
}
show_url_in_args() {
while [ $# -gt 0 ]; do
case "$1" in
[Hh][Tt][Tt][Pp][Ss]://* | [Hh][Tt][Tt][Pp]://* | [Mm][Aa][Gg][Nn][Ee][Tt]:*) echo "$1" ;;
esac
shift
done
}
curl() { curl() {
is_have_cmd curl || install_pkg curl is_have_cmd curl || install_pkg curl
# 显示 url
show_url_in_args "$@" >&2
# 添加 -f, --fail不然 404 退出码也为0 # 添加 -f, --fail不然 404 退出码也为0
# 32位 cygwin 已停止更新,证书可能有问题,先添加 --insecure # 32位 cygwin 已停止更新,证书可能有问题,先添加 --insecure
# centos 7 curl 不支持 --retry-connrefused --retry-all-errors # centos 7 curl 不支持 --retry-connrefused --retry-all-errors
# 因此手动 retry # 因此手动 retry
grep -o 'http[^ ]*' <<<"$@" >&2
for i in $(seq 5); do for i in $(seq 5); do
if command curl --insecure --connect-timeout 10 -f "$@"; then if command curl --insecure --connect-timeout 10 -f "$@"; then
return return
@ -280,11 +314,21 @@ get_function_content() {
} }
insert_into_file() { insert_into_file() {
file=$1 local file=$1
location=$2 local location=$2
regex_to_find=$3 local regex_to_find=$3
shift 3
line_num=$(grep -E -n "$regex_to_find" "$file" | cut -d: -f1) if ! [ -f "$file" ]; then
error_and_exit "File not found: $file"
fi
# 默认 grep -E
if [ $# -eq 0 ]; then
set -- -E
fi
line_num=$(grep "$@" -n "$regex_to_find" "$file" | cut -d: -f1)
found_count=$(echo "$line_num" | wc -l) found_count=$(echo "$line_num" | wc -l)
if [ ! "$found_count" -eq 1 ]; then if [ ! "$found_count" -eq 1 ]; then
@ -813,30 +857,22 @@ is_have_arm_version() {
case "$version" in case "$version" in
10) 10)
case "$edition" in case "$edition" in
pro | education | enterprise | 'pro education' | 'pro for workstations') return ;; home | 'home single language' | pro | education | enterprise | 'pro education' | 'pro for workstations') return ;;
'iot enterprise') return ;; 'iot enterprise') return ;;
# arm ltsc 只有 2021 有 iso
'enterprise ltsc 2021' | 'iot enterprise ltsc 2021') return ;; 'enterprise ltsc 2021' | 'iot enterprise ltsc 2021') return ;;
esac esac
;; ;;
11) 11) return ;;
case "$edition" in
pro | education | enterprise | 'pro education' | 'pro for workstations') return ;;
'iot enterprise' | 'iot enterprise subscription') return ;;
'enterprise ltsc 2024' | 'iot enterprise ltsc 2024' | 'iot enterprise ltsc 2024 subscription') return ;;
esac
;;
esac esac
return 1 return 1
} }
find_windows_iso() { find_windows_iso() {
parse_windows_image_name || error_and_exit "--image-name wrong: $image_name" parse_windows_image_name || error_and_exit "--image-name wrong: $image_name"
if ! [ "$version" = 8.1 ] && [ -z "$edition" ]; then if ! { [ "$version" = 8 ] || [ "$version" = 8.1 ]; } && [ -z "$edition" ]; then
error_and_exit "Edition is not set." error_and_exit "Edition is not set."
fi fi
if [ "$basearch" = 'aarch64' ] && ! is_have_arm_version; then
error_and_exit "No ARM iso for this Windows Version."
fi
if [ -z "$lang" ]; then if [ -z "$lang" ]; then
lang=en-us lang=en-us
@ -883,7 +919,8 @@ get_windows_iso_link() {
x86) echo _ ;; x86) echo _ ;;
esac esac
;; ;;
homebasic | homepremium | business | ultimate) echo _ ;; homebasic | homepremium | ultimate) echo _ ;;
business | enterprise) echo "$edition" ;;
esac esac
;; ;;
7) 7)
@ -902,17 +939,22 @@ get_windows_iso_link() {
professional | enterprise | ultimate) echo "$edition" ;; professional | enterprise | ultimate) echo "$edition" ;;
esac esac
;; ;;
# massgrave 不提供 windows 8 下载 8 | 8.1)
8.1)
case "$edition" in case "$edition" in
'') echo _ ;; # windows 8.1 core '') echo _ ;; # windows 8.x core
pro | enterprise) echo "$edition" ;; pro | enterprise) echo "$edition" ;;
esac esac
;; ;;
10) 10)
case "$edition" in case "$edition" in
home | 'home single language') echo consumer ;; home | 'home single language') echo consumer ;;
pro | education | enterprise | 'pro education' | 'pro for workstations') echo business ;; pro | enterprise) echo business ;;
education | 'pro education' | 'pro for workstations')
case "$arch_win" in
arm64) echo consumer ;;
x64) echo business ;; # iso 更小
esac
;;
# iot # iot
'iot enterprise') echo 'iot enterprise' ;; 'iot enterprise') echo 'iot enterprise' ;;
# iot ltsc # iot ltsc
@ -929,13 +971,23 @@ get_windows_iso_link() {
esac esac
;; ;;
11) 11)
# arm business iso 都没有 education, pro education, pro for workstations
# 即使它的名字包含 EDU
# SW_DVD9_Win_Pro_10_22H2.31_Arm64_English_Pro_Ent_EDU_N_MLF_X24-05074.ISO
# en-us_windows_11_business_editions_version_25h2_arm64_dvd_8afc9b39.iso
case "$edition" in case "$edition" in
home | 'home single language') echo consumer ;; home | 'home single language') echo consumer ;;
pro | education | enterprise | 'pro education' | 'pro for workstations') echo business ;; pro | enterprise) echo business ;;
education | 'pro education' | 'pro for workstations')
case "$arch_win" in
arm64) echo consumer ;;
x64) echo business ;; # iso 更小
esac
;;
# iot # iot
'iot enterprise' | 'iot enterprise subscription') echo 'iot enterprise' ;; 'iot enterprise' | 'iot enterprise subscription') echo 'iot enterprise' ;;
# iot ltsc # iot ltsc
'iot enterprise ltsc 2024' | 'iot enterprise ltsc 2024 subscription') echo 'iot enterprise ltsc 2024' ;; 'iot enterprise ltsc 2024' | 'iot enterprise subscription ltsc 2024') echo 'iot enterprise ltsc 2024' ;;
# ltsc # ltsc
'enterprise ltsc 2024') 'enterprise ltsc 2024')
# arm64 的 enterprise ltsc 2024 要下载 iot enterprise ltsc 2024 iso # arm64 的 enterprise ltsc 2024 要下载 iot enterprise ltsc 2024 iso
@ -960,8 +1012,11 @@ get_windows_iso_link() {
esac esac
} }
# 8.1 和 11 arm 没有每月发布 iso # msdl 没有每月发布 iso
# 因此优先从 msdl 下载 # msdl 只有 consumer 版本,因此里面的 pro 版本不是 vl 版
# 8.1 没有每月发布的 iso因此优先从 msdl 下载
# win10 22h2 arm 有每月发布的 iso因此不从 msdl 下载
# win10/11 ltsc 没有每月发布的 iso但是 msdl 没有 ltsc 版本
get_label_msdl() { get_label_msdl() {
case "$version" in case "$version" in
8.1) 8.1)
@ -969,15 +1024,6 @@ get_windows_iso_link() {
'' | pro) echo _ ;; '' | pro) echo _ ;;
esac esac
;; ;;
11)
case "$edition" in
home | 'home single language' | pro | education | 'pro education' | 'pro for workstations')
case "$arch_win" in
arm64) echo _ ;;
esac
;;
esac
;;
esac esac
} }
@ -990,7 +1036,7 @@ get_windows_iso_link() {
echo server echo server
else else
case "$version" in case "$version" in
vista | 7 | 8.1 | 10 | 11) vista | 7 | 8 | 8.1 | 10 | 11)
echo "$version" echo "$version"
;; ;;
esac esac
@ -1024,14 +1070,23 @@ get_windows_iso_link() {
echo "List: $page_url" echo "List: $page_url"
echo echo
# 先判断是否能自动查找该版本
# 再判断是否支持 arm
# 这样可以在输入错误 Edition 时例如 windows 11 enterprise ltsc 2021
# 显示名称错误,而不是显示该版本不支持 arm
if [ -z "$page" ] || { [ -z "$label_msdn" ] && [ -z "$label_msdl" ] && [ -z "$label_vlsc" ]; }; then if [ -z "$page" ] || { [ -z "$label_msdn" ] && [ -z "$label_msdl" ] && [ -z "$label_vlsc" ]; }; then
error_and_exit "Not support find this iso. Check if --image-name is wrong. If not, set --iso manually." error_and_exit "Not support find this iso. Check if --image-name is wrong. Or set --iso manually."
fi
if [ "$basearch" = aarch64 ] && ! is_have_arm_version; then
error_and_exit "No ARM iso for this Windows Version or Edition."
fi fi
if [ -n "$label_msdl" ]; then if [ -n "$label_msdl" ]; then
iso=$(curl -L "$page_url" | grep -ioP 'https://.*?#[0-9]+' | head -1 | grep .) iso=$(curl -L "$page_url" | grep -ioP 'https://[^ ]+?#[0-9]+' | head -1 | grep .)
else else
curl -L "$page_url" | grep -ioP 'https://.*?.(iso|img)' >$tmp/win.list curl -L "$page_url" | grep -ioP 'https://[^ ]+?.(iso|img)' >$tmp/win.list
# 如果不是 ltsc ,应该先去除 ltsc 链接,否则最终链接有 ltsc 的 # 如果不是 ltsc ,应该先去除 ltsc 链接,否则最终链接有 ltsc 的
# 例如查找 windows 10 iot enterprise会得到 # 例如查找 windows 10 iot enterprise会得到
@ -1130,6 +1185,10 @@ setos() {
[ "$releasever" -le 10 ] [ "$releasever" -le 10 ]
} }
if [ "$releasever" -le 9 ] && [ "$basearch" = aarch64 ]; then
error_and_exit "Debian $releasever ELTS does not support aarch64."
fi
# 用此标记要是否 elts, 用于安装后修改 elts/etls-cn 源 # 用此标记要是否 elts, 用于安装后修改 elts/etls-cn 源
# shellcheck disable=SC2034 # shellcheck disable=SC2034
is_debian_elts && elts=1 || elts=0 is_debian_elts && elts=1 || elts=0
@ -1248,6 +1307,7 @@ Continue?
eval ${step}_vmlinuz=$mirror/linux eval ${step}_vmlinuz=$mirror/linux
eval ${step}_initrd=$mirror/initrd.gz eval ${step}_initrd=$mirror/initrd.gz
eval ${step}_ks=$confhome/debian.cfg eval ${step}_ks=$confhome/debian.cfg
eval ${step}_deb_mirror=$hostname/kali
eval ${step}_udeb_mirror=$hostname/kali eval ${step}_udeb_mirror=$hostname/kali
eval ${step}_codename=$codename eval ${step}_codename=$codename
eval ${step}_kernel=linux-image$flavour-$basearch_alt eval ${step}_kernel=linux-image$flavour-$basearch_alt
@ -1438,8 +1498,8 @@ Continue?
dir=distribution/leap/$releasever/appliances dir=distribution/leap/$releasever/appliances
case "$releasever" in case "$releasever" in
15.6) file=openSUSE-Leap-$releasever-Minimal-VM.$basearch-Cloud.qcow2 ;; 15.6) file=openSUSE-Leap-$releasever-Minimal-VM.$basearch-Cloud.qcow2 ;;
# 16.0) file=Leap-$releasever-Minimal-VM.$basearch-Cloud.qcow2 ;; # 缺少 openSUSE-repos-Leap 包,导致没有源 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-kvm$(if [ "$basearch" = x86_64 ]; then echo '-and-xen'; fi).qcow2 ;;
esac esac
# https://src.opensuse.org/openSUSE/Leap-Images/src/branch/leap-16.0/kiwi-templates-Minimal/Minimal.kiwi # https://src.opensuse.org/openSUSE/Leap-Images/src/branch/leap-16.0/kiwi-templates-Minimal/Minimal.kiwi
@ -1858,11 +1918,12 @@ verify_os_name() {
'almalinux 8|9|10' \ 'almalinux 8|9|10' \
'rocky 8|9|10' \ 'rocky 8|9|10' \
'oracle 8|9|10' \ 'oracle 8|9|10' \
'fedora 41|42' \ 'fnos 1' \
'nixos 25.05' \ 'fedora 42|43' \
'nixos 25.11' \
'debian 9|10|11|12|13' \ 'debian 9|10|11|12|13' \
'opensuse 15.6|16.0|tumbleweed' \ 'opensuse 15.6|16.0|tumbleweed' \
'alpine 3.19|3.20|3.21|3.22' \ 'alpine 3.20|3.21|3.22|3.23' \
'openeuler 20.03|22.03|24.03|25.09' \ 'openeuler 20.03|22.03|24.03|25.09' \
'ubuntu 16.04|18.04|20.04|22.04|24.04|25.10' \ 'ubuntu 16.04|18.04|20.04|22.04|24.04|25.10' \
'redhat' \ 'redhat' \
@ -1870,7 +1931,6 @@ verify_os_name() {
'arch' \ 'arch' \
'gentoo' \ 'gentoo' \
'aosc' \ 'aosc' \
'fnos' \
'windows' \ 'windows' \
'dd' \ 'dd' \
'netboot.xyz'; do 'netboot.xyz'; do
@ -1924,8 +1984,7 @@ install_pkg() {
# 因为可能装了多种包管理器 # 因为可能装了多种包管理器
if [ -f /etc/os-release ]; then if [ -f /etc/os-release ]; then
# shellcheck source=/dev/null # shellcheck source=/dev/null
. /etc/os-release for id in $({ . /etc/os-release && echo $ID $ID_LIKE; }); do
for id in $ID $ID_LIKE; do
# https://github.com/chef/os_release # https://github.com/chef/os_release
case "$id" in case "$id" in
fedora | centos | rhel) is_have_cmd dnf && pkg_mgr=dnf || pkg_mgr=yum ;; fedora | centos | rhel) is_have_cmd dnf && pkg_mgr=dnf || pkg_mgr=yum ;;
@ -2281,6 +2340,10 @@ del_empty_lines() {
sed '/^[[:space:]]*$/d' sed '/^[[:space:]]*$/d'
} }
del_comment_lines() {
sed '/^[[:space:]]*#/d'
}
trim() { trim() {
# sed -E -e 's/^[[:space:]]+//' -e 's/[[:space:]]+$//' # sed -E -e 's/^[[:space:]]+//' -e 's/[[:space:]]+$//'
sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//'
@ -2288,16 +2351,23 @@ trim() {
prompt_password() { prompt_password() {
info "prompt password" info "prompt password"
warn false "Leave blank to use a random password."
warn false "不填写则使用随机密码"
while true; do while true; do
IFS= read -r -p "Password [$DEFAULT_PASSWORD]: " password IFS= read -r -p "Password: " password
IFS= read -r -p "Retype password [$DEFAULT_PASSWORD]: " password_confirm if [ -n "$password" ]; then
password=${password:-$DEFAULT_PASSWORD} IFS= read -r -p "Retype password: " password_confirm
password_confirm=${password_confirm:-$DEFAULT_PASSWORD} if [ "$password" = "$password_confirm" ]; then
if [ -z "$password" ]; then break
error "Passwords is empty. Try again."
elif [ "$password" != "$password_confirm" ]; then
error "Passwords don't match. Try again."
else else
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)
break break
fi fi
done done
@ -2756,7 +2826,8 @@ install_grub_linux_efi() {
info 'download grub efi' info 'download grub efi'
# fedora 39 的 efi 无法识别 opensuse tumbleweed 的 xfs # fedora 39 的 efi 无法识别 opensuse tumbleweed 的 xfs
efi_distro=fedora efi_distro=opensuse
grub_efi=$(get_grub_efi_filename) grub_efi=$(get_grub_efi_filename)
# 不要用 download.opensuse.org 和 download.fedoraproject.org # 不要用 download.opensuse.org 和 download.fedoraproject.org
@ -2771,6 +2842,7 @@ install_grub_linux_efi() {
# dl.fedoraproject.org 不支持 ipv6 # dl.fedoraproject.org 不支持 ipv6
if [ "$efi_distro" = fedora ]; then if [ "$efi_distro" = fedora ]; then
# fedora 43 efi 在 vultr 无法引导 debain 9/10 netboot
fedora_ver=$(get_latest_distro_releasever fedora) fedora_ver=$(get_latest_distro_releasever fedora)
if is_in_china; then if is_in_china; then
@ -3004,7 +3076,11 @@ build_nextos_cmdline() {
if [ $nextos_distro = alpine ]; then if [ $nextos_distro = alpine ]; then
nextos_cmdline="alpine_repo=$nextos_repo modloop=$nextos_modloop" nextos_cmdline="alpine_repo=$nextos_repo modloop=$nextos_modloop"
elif is_distro_like_debian $nextos_distro; then elif is_distro_like_debian $nextos_distro; then
# 设置分辨率为800*600防止分辨率过高 ssh screen attach 后无法全部显示
# iso 默认有 vga=788
# 如果要设置位数: video=800x600-16
nextos_cmdline="lowmem/low=1 auto=true priority=critical" nextos_cmdline="lowmem/low=1 auto=true priority=critical"
# nextos_cmdline+=" vga=788 video=800x600"
nextos_cmdline+=" url=$nextos_ks" nextos_cmdline+=" url=$nextos_ks"
nextos_cmdline+=" mirror/http/hostname=${nextos_udeb_mirror%/*}" nextos_cmdline+=" mirror/http/hostname=${nextos_udeb_mirror%/*}"
nextos_cmdline+=" mirror/http/directory=/${nextos_udeb_mirror##*/}" nextos_cmdline+=" mirror/http/directory=/${nextos_udeb_mirror##*/}"
@ -3069,9 +3145,9 @@ mkdir_clear() {
# 再次运行时,有可能 mount 了 btrfs root因此先要 umount_all # 再次运行时,有可能 mount 了 btrfs root因此先要 umount_all
# 但目前不需要 mount ,因此用不到 # 但目前不需要 mount ,因此用不到
# umount_all $dir # umount_all "$dir"
rm -rf $dir rm -rf "$dir"
mkdir -p $dir mkdir -p "$dir"
} }
mod_initrd_debian_kali() { mod_initrd_debian_kali() {
@ -3080,6 +3156,14 @@ mod_initrd_debian_kali() {
sed -Ei 's,&&( onlink=),||\1,' etc/udhcpc/default.script sed -Ei 's,&&( onlink=),||\1,' etc/udhcpc/default.script
# hack 2 # hack 2
# 强制使用 screen
# shellcheck disable=SC1003,SC2016
{
echo 'if false && : \' | insert_into_file lib/debian-installer.d/S70menu before 'if [ -x "$bterm" ]' -F
echo 'if true || : \' | insert_into_file lib/debian-installer.d/S70menu before 'if [ -x "$screen_bin" -a' -F
}
# hack 3
# 修改 /var/lib/dpkg/info/netcfg.postinst 运行我们的脚本 # 修改 /var/lib/dpkg/info/netcfg.postinst 运行我们的脚本
netcfg() { netcfg() {
#!/bin/sh #!/bin/sh
@ -3091,18 +3175,24 @@ mod_initrd_debian_kali() {
# 运行 trans.sh保存配置 # 运行 trans.sh保存配置
db_progress INFO base-installer/progress/netcfg db_progress INFO base-installer/progress/netcfg
sh /trans.sh # 添加 || exit ,可以在 debian installer 不兼容 /trans.sh 语法时强制报错
# exit 不带参数,返回值为 || 前面命令的返回值
sh /trans.sh || exit
db_progress STEP 1 db_progress STEP 1
db_progress STOP
} }
# 直接覆盖 net-retriever方便调试
# curl -Lo /usr/lib/debian-installer/retriever/net-retriever $confhome/net-retriever
postinst=var/lib/dpkg/info/netcfg.postinst postinst=var/lib/dpkg/info/netcfg.postinst
get_function_content netcfg >$postinst get_function_content netcfg >$postinst
get_ip_conf_cmd | insert_into_file $postinst after ": get_ip_conf_cmd" get_ip_conf_cmd | insert_into_file $postinst after ": get_ip_conf_cmd"
# cat $postinst # cat $postinst
# hack 4
# 修改 udeb 依赖
# 直接覆盖 net-retriever方便调试
# curl -Lo /usr/lib/debian-installer/retriever/net-retriever $confhome/net-retriever
change_priority() { change_priority() {
while IFS= read -r line; do while IFS= read -r line; do
if [[ "$line" = Package:* ]]; then if [[ "$line" = Package:* ]]; then
@ -3186,32 +3276,44 @@ EOF
# 云内核没有 sata 模块,也没有内嵌,有一个 CONFIG_SATA_HOST=ylibata-$(CONFIG_SATA_HOST) += libata-sata.o # 云内核没有 sata 模块,也没有内嵌,有一个 CONFIG_SATA_HOST=ylibata-$(CONFIG_SATA_HOST) += libata-sata.o
# scsi-modules 默认安装(改成可选),包含 nvme.ko(+) 和各种虚拟化驱动(+) # scsi-modules 默认安装(改成可选),包含 nvme.ko(+) 和各种虚拟化驱动(+)
download_and_extract_udeb() { download_and_extract_deb() {
package=$1 local type=$1
extract_dir=$2 local package=$2
local extract_dir=$3
# 获取 udeb 列表
udeb_list=$tmp/udeb_list
if ! [ -f $udeb_list ]; then
# shellcheck disable=SC2154 # shellcheck disable=SC2154
curl -L http://$nextos_udeb_mirror/dists/$nextos_codename/main/debian-installer/binary-$basearch_alt/Packages.gz | case "$type" in
zcat | grep 'Filename:' | awk '{print $2}' >$udeb_list deb)
local mirror=$nextos_deb_mirror
local url=http://$mirror/dists/$nextos_codename/main/binary-$basearch_alt/Packages.gz
;;
udeb)
local mirror=$nextos_udeb_mirror
local url=http://$mirror/dists/$nextos_codename/main/debian-installer/binary-$basearch_alt/Packages.gz
;;
esac
# 获取 deb/udeb 列表
deb_list=$tmp/${type}_list
if ! [ -f $deb_list ]; then
curl -L "$url" | zcat | grep 'Filename:' | awk '{print $2}' >$deb_list
fi fi
# 下载 udeb # 下载 deb/udeb
curl -Lo $tmp/tmp.udeb http://$nextos_udeb_mirror/"$(grep -F /${package}_ $udeb_list)" deb_path=$(grep -F "/${package}_" "$deb_list")
curl -Lo $tmp/tmp.deb http://$mirror/"$deb_path"
if false; then if false; then
# 使用 dpkg # 使用 dpkg
# cygwin 没有 dpkg # cygwin 没有 dpkg
install_pkg dpkg install_pkg dpkg
dpkg -x $tmp/tmp.udeb $extract_dir dpkg -x $tmp/tmp.deb $extract_dir
else else
# 使用 ar tar xz # 使用 ar tar xz
# cygwin 需安装 binutils # cygwin 需安装 binutils
# centos7 ar 不支持 --output # centos7 ar 不支持 --output
install_pkg ar tar xz install_pkg ar tar xz
(cd $tmp && ar x $tmp/tmp.udeb) (cd $tmp && ar x $tmp/tmp.deb)
tar xf $tmp/data.tar.xz -C $extract_dir tar xf $tmp/data.tar.xz -C $extract_dir
fi fi
} }
@ -3255,12 +3357,27 @@ EOF
curl -Lo usr/share/keyrings/debian-archive-keyring.gpg https://deb.freexian.com/extended-lts/archive-key.gpg curl -Lo usr/share/keyrings/debian-archive-keyring.gpg https://deb.freexian.com/extended-lts/archive-key.gpg
fi fi
# 提前下载 sshd
# 以便在配置下载源之前就可以启动 sshd
mkdir_clear $tmp/sshd
download_and_extract_deb udeb openssh-server-udeb $tmp/sshd
cp -r $tmp/sshd/* .
# 提前下载 fdisk # 提前下载 fdisk
# 因为 fdisk-udeb 包含 fdisk 和 sfdisk提前下载可减少占用 # 因为 fdisk-udeb 包含 fdisk 和 sfdisk提前下载可减少占用
mkdir_clear $tmp/fdisk mkdir_clear $tmp/fdisk
download_and_extract_udeb fdisk-udeb $tmp/fdisk download_and_extract_deb udeb fdisk-udeb $tmp/fdisk
cp -f $tmp/fdisk/usr/sbin/fdisk usr/sbin/ cp -f $tmp/fdisk/usr/sbin/fdisk usr/sbin/
# 下载 websocketd
# debian 11+ 才有 websocketd
if [ "$distro" = kali ] ||
{ [ "$distro" = debian ] && [ "$releasever" -ge 11 ]; }; then
mkdir_clear $tmp/websocketd
download_and_extract_deb deb websocketd $tmp/websocketd
cp -f $tmp/websocketd/usr/bin/websocketd usr/bin/
fi
# >256M 或者当前系统是 windows # >256M 或者当前系统是 windows
if [ $ram_size -gt 256 ] || is_in_windows; then if [ $ram_size -gt 256 ] || is_in_windows; then
sed -i '/^pata-modules/d' $net_retriever sed -i '/^pata-modules/d' $net_retriever
@ -3291,7 +3408,7 @@ EOF
# 但反查也找不到 curl https://deb.debian.org/debian/dists/bookworm/main/Contents-udeb-amd64.gz | zcat | grep xen # 但反查也找不到 curl https://deb.debian.org/debian/dists/bookworm/main/Contents-udeb-amd64.gz | zcat | grep xen
if [ -n "$extra_drivers" ]; then if [ -n "$extra_drivers" ]; then
mkdir_clear $tmp/scsi mkdir_clear $tmp/scsi
download_and_extract_udeb scsi-modules-$kver-di $tmp/scsi download_and_extract_deb udeb scsi-modules-$kver-di $tmp/scsi
relative_drivers_dir=lib/modules/$kver/kernel/drivers relative_drivers_dir=lib/modules/$kver/kernel/drivers
udeb_drivers_dir=$tmp/scsi/$relative_drivers_dir udeb_drivers_dir=$tmp/scsi/$relative_drivers_dir
@ -3627,6 +3744,11 @@ This script is outdated, please download reinstall.sh again.
remove_useless_initrd_files remove_useless_initrd_files
fi fi
if [ "$hold" = 0 ]; then
info 'hold 0'
read -r -p 'Press Enter to continue...'
fi
# 重建 # 重建
# 注意要用 cpio -H newc 不要用 cpio -c ,不同版本的 -c 作用不一样,很坑 # 注意要用 cpio -H newc 不要用 cpio -c ,不同版本的 -c 作用不一样,很坑
# -c Use the old portable (ASCII) archive format # -c Use the old portable (ASCII) archive format
@ -3654,14 +3776,15 @@ remove_useless_initrd_files() {
for item in *; do for item in *; do
case "$item" in case "$item" in
# 甲骨文 arm 用自定义镜像支持设为 mlx5 vf 网卡,且不是 azure 那样显示两个网卡 # 甲骨文 arm 用自定义镜像支持设为 mlx5 vf 网卡,且不是 azure 那样显示两个网卡
amazon | google | mellanox | realtek) ;; # https://debian.pkgs.org/13/debian-main-amd64/linux-image-6.12.43+deb13-cloud-amd64_6.12.43-1_amd64.deb.html
amazon | google | mellanox | realtek | pensando) ;;
intel) intel)
( (
cd "$item" cd "$item"
for sub_item in *; do for sub_item in *; do
case "$sub_item" in case "$sub_item" in
# 有 e100.ko e1000文件夹 e1000e文件夹 # 有 e100.ko e1000文件夹 e1000e文件夹
e100* | lib* | *vf) ;; e100* | lib* | *vf | idpf) ;;
*) rm -rf $sub_item ;; *) rm -rf $sub_item ;;
esac esac
done done
@ -3715,6 +3838,7 @@ get_unix_path() {
} }
# 脚本入口 # 脚本入口
if mount | grep -q 'tmpfs on / type tmpfs'; then if mount | grep -q 'tmpfs on / type tmpfs'; then
error_and_exit "Can't run this script in Live OS." error_and_exit "Can't run this script in Live OS."
fi fi
@ -3781,10 +3905,15 @@ for o in ci installer debug minimal allow-ping force-cn help \
done done
# 整理参数 # 整理参数
if ! opts=$(getopt -n $0 -o "h" --long "$long_opts" -- "$@"); then if ! opts=$(getopt -n $0 -o "h,x" --long "$long_opts" -- "$@"); then
exit exit
fi fi
# /tmp 挂载在内存的话,可能不够空间
# 处理 --frpc--toml 时会下载文件,因此在处理参数前就创建临时目录
tmp=/reinstall-tmp
mkdir_clear "$tmp"
eval set -- "$opts" eval set -- "$opts"
# shellcheck disable=SC2034 # shellcheck disable=SC2034
while true; do while true; do
@ -3796,7 +3925,7 @@ while true; do
commit=$2 commit=$2
shift 2 shift 2
;; ;;
--debug) -x | --debug)
set -x set -x
shift shift
;; ;;
@ -3824,7 +3953,7 @@ while true; do
shift shift
;; ;;
--hold | --sleep) --hold | --sleep)
if ! { [ "$2" = 1 ] || [ "$2" = 2 ]; }; then if ! { [ "$2" = 0 ] || [ "$2" = 1 ] || [ "$2" = 2 ]; }; then
error_and_exit "Invalid $1 value: $2" error_and_exit "Invalid $1 value: $2"
fi fi
hold=$2 hold=$2
@ -3833,16 +3962,21 @@ while true; do
--frpc-conf | --frpc-config | --frpc-toml) --frpc-conf | --frpc-config | --frpc-toml)
[ -n "$2" ] || error_and_exit "Need value for $1" [ -n "$2" ] || error_and_exit "Need value for $1"
# windows 路径转换 case "$(to_lower <<<"$2")" in
frpc_config=$(get_unix_path "$2") http://* | https://*)
frpc_config_url=$2
# alpine busybox 不支持 readlink -m frpc_config=$tmp/frpc_config
# readlink -m /asfsafasfsaf/fasf if ! curl -L "$frpc_config_url" -o "$frpc_config"; then
# 因此需要先判断路径是否存在 error_and_exit "Can't get frpc config from $frpc_config_url"
if ! [ -f "$frpc_config" ]; then
error_and_exit "Not a toml file: $2"
fi fi
;;
*)
# windows 路径转换
if ! { frpc_config=$(get_unix_path "$2") && [ -f "$frpc_config" ]; }; then
error_and_exit "File not exists: $2"
fi
;;
esac
# 转为绝对路径 # 转为绝对路径
frpc_config=$(readlink -f "$frpc_config") frpc_config=$(readlink -f "$frpc_config")
@ -3881,7 +4015,7 @@ EOF
# https://manpages.debian.org/testing/openssh-server/authorized_keys.5.en.html#AUTHORIZED_KEYS_FILE_FORMAT # https://manpages.debian.org/testing/openssh-server/authorized_keys.5.en.html#AUTHORIZED_KEYS_FILE_FORMAT
is_valid_ssh_key() { is_valid_ssh_key() {
grep -qE '^(ecdsa-sha2-nistp(256|384|512)|ssh-(ed25519|rsa)) ' <<<"$1" grep -qE '^(ecdsa-sha2-nistp(256|384|521)|ssh-(ed25519|rsa)) ' <<<"$1"
} }
[ -n "$2" ] || ssh_key_error_and_exit "Need value for $1" [ -n "$2" ] || ssh_key_error_and_exit "Need value for $1"
@ -4034,13 +4168,7 @@ fi
# 密码 # 密码
if ! is_netboot_xyz && [ -z "$ssh_keys" ] && [ -z "$password" ]; then if ! is_netboot_xyz && [ -z "$ssh_keys" ] && [ -z "$password" ]; then
if is_use_dd; then if is_use_dd; then
echo " show_dd_password_tips
This password is only used for SSH access to view logs during the installation.
Password of the image will NOT modify.
密码仅用于安装过程中通过 SSH 查看日志。
镜像的密码不会被修改。
"
fi fi
prompt_password prompt_password
fi fi
@ -4048,10 +4176,6 @@ fi
# 必备组件 # 必备组件
install_pkg curl grep install_pkg curl grep
# /tmp 挂载在内存的话,可能不够空间
tmp=/reinstall-tmp
mkdir_clear "$tmp"
# 强制忽略/强制添加 --ci 参数 # 强制忽略/强制添加 --ci 参数
# debian 不强制忽略 ci 留作测试 # debian 不强制忽略 ci 留作测试
case "$distro" in case "$distro" in
@ -4460,13 +4584,18 @@ EOF
get_function_content load_grubenv_if_not_loaded >$target_cfg get_function_content load_grubenv_if_not_loaded >$target_cfg
# 原系统为 openeuler 云镜像,需要添加 --unrestricted否则要输入密码 # 原系统为 openeuler 云镜像,需要添加 --unrestricted否则要输入密码
del_empty_lines <<EOF | tee -a $target_cfg del_empty_lines <<EOF | del_comment_lines | tee -a $target_cfg
set timeout_style=menu set timeout_style=menu
set timeout=5 set timeout=5
menuentry "$(get_entry_name)" --unrestricted { menuentry "$(get_entry_name)" --unrestricted {
$(! is_in_windows && echo 'insmod lvm') $(! is_in_windows && echo 'insmod lvm')
$(is_os_in_btrfs && echo 'set btrfs_relative_path=n') $(is_os_in_btrfs && echo 'set btrfs_relative_path=n')
# fedora efi 没有 load_video
insmod all_video insmod all_video
# set gfxmode=800x600
# set gfxpayload=keep
# terminal_output gfxterm 在 vultr 上会花屏
# terminal_output console
search --no-floppy --file --set=root $vmlinuz search --no-floppy --file --set=root $vmlinuz
$linux_cmd $vmlinuz $cmdline $linux_cmd $vmlinuz $cmdline
$([ -n "$initrds" ] && echo "$initrd_cmd $initrds") $([ -n "$initrds" ] && echo "$initrd_cmd $initrds")
@ -4485,8 +4614,8 @@ echo "$distro $releasever"
case "$distro" in case "$distro" in
windows) username=administrator ;; windows) username=administrator ;;
dd | netboot.xyz) username= ;; netboot.xyz) username= ;;
*) username=root ;; dd | *) username=root ;;
esac esac
if [ -n "$username" ]; then if [ -n "$username" ]; then
@ -4503,6 +4632,7 @@ if is_netboot_xyz; then
elif is_alpine_live; then elif is_alpine_live; then
echo 'Reboot to start Alpine Live OS.' echo 'Reboot to start Alpine Live OS.'
elif is_use_dd; then elif is_use_dd; then
show_dd_password_tips
echo 'Reboot to start DD.' echo 'Reboot to start DD.'
elif [ "$distro" = fnos ]; then elif [ "$distro" = fnos ]; then
echo "Special note for FNOS:" echo "Special note for FNOS:"

174
trans.sh
View File

@ -10,7 +10,7 @@ set -eE
# 用于判断 reinstall.sh 和 trans.sh 是否兼容 # 用于判断 reinstall.sh 和 trans.sh 是否兼容
# shellcheck disable=SC2034 # shellcheck disable=SC2034
SCRIPT_VERSION=4BACD833-A585-23BA-6CBB-9AA4E08E0003 SCRIPT_VERSION=4BACD833-A585-23BA-6CBB-9AA4E08E0004
TRUE=0 TRUE=0
FALSE=1 FALSE=1
@ -87,11 +87,20 @@ apk() {
retry 5 command apk "$@" >&2 retry 5 command apk "$@" >&2
} }
show_url_in_args() {
while [ $# -gt 0 ]; do
case "$1" in
[Hh][Tt][Tt][Pp][Ss]://* | [Hh][Tt][Tt][Pp]://* | [Mm][Aa][Gg][Nn][Ee][Tt]:*) echo "$1" ;;
esac
shift
done
}
# 在没有设置 set +o pipefail 的情况下,限制下载大小: # 在没有设置 set +o pipefail 的情况下,限制下载大小:
# retry 5 command wget | head -c 1048576 会触发 retry下载 5 次 # retry 5 command wget | head -c 1048576 会触发 retry下载 5 次
# command wget "$@" --tries=5 | head -c 1048576 不会触发 wget 自带的 retry只下载 1 次 # command wget "$@" --tries=5 | head -c 1048576 不会触发 wget 自带的 retry只下载 1 次
wget() { wget() {
echo "$@" | grep -o 'http[^ ]*' >&2 show_url_in_args "$@" >&2
if command wget 2>&1 | grep -q BusyBox; then if command wget 2>&1 | grep -q BusyBox; then
# busybox wget 没有重试功能 # busybox wget 没有重试功能
# 好像默认永不超时 # 好像默认永不超时
@ -194,7 +203,8 @@ download() {
url=$torrent url=$torrent
fi fi
# intel 禁止了 aria2 下载 # intel 禁止了 aria2 下载驱动
# intel 禁止了 wget 下载网页内容
# 腾讯云 virtio 驱动也禁止了 aria2 下载 # 腾讯云 virtio 驱动也禁止了 aria2 下载
# -o 设置 http 下载文件名 # -o 设置 http 下载文件名
@ -203,7 +213,7 @@ download() {
-d "$(dirname "$path")" \ -d "$(dirname "$path")" \
-o "$(basename "$path")" \ -o "$(basename "$path")" \
-O "1=$(basename "$path")" \ -O "1=$(basename "$path")" \
-U Wget/1.25.0 -U curl/7.54.1
# opensuse 官方镜像支持 metalink # opensuse 官方镜像支持 metalink
# aira2 无法重命名用 metalink 下载的文件 # aira2 无法重命名用 metalink 下载的文件
@ -294,7 +304,7 @@ setup_websocketd() {
pkill websocketd || true pkill websocketd || true
# websocketd 遇到 \n 才推送,因此要转换 \r 为 \n # websocketd 遇到 \n 才推送,因此要转换 \r 为 \n
websocketd --port "$web_port" --loglevel=fatal --staticdir=/tmp \ websocketd --port "$web_port" --loglevel=fatal --staticdir=/tmp \
stdbuf -oL -eL sh -c "tail -fn+0 /reinstall.log | tr '\r' '\n'" & stdbuf -oL -eL sh -c "tail -fn+0 /reinstall.log | tr '\r' '\n' | grep -Fiv -e password -e token" &
} }
get_approximate_ram_size() { get_approximate_ram_size() {
@ -313,7 +323,7 @@ get_approximate_ram_size() {
setup_web_if_enough_ram() { setup_web_if_enough_ram() {
total_ram=$(get_approximate_ram_size) total_ram=$(get_approximate_ram_size)
# 512内存才安装 # 512内存才安装
if [ $total_ram -gt 400 ]; then if [ "$total_ram" -ge 400 ]; then
# lighttpd 虽然运行占用内存少,但安装占用空间大 # lighttpd 虽然运行占用内存少,但安装占用空间大
# setup_lighttpd # setup_lighttpd
# setup_nginx # setup_nginx
@ -758,17 +768,19 @@ is_windows_support_rdnss() {
[ "$build_ver" -ge 15063 ] [ "$build_ver" -ge 15063 ]
} }
get_windows_version_from_dll() { get_windows_version_from_windows_drive() {
local dll=$1 local os_dir=$1
[ -f "$dll" ] || error_and_exit "File not found: $dll"
apk add pev apk add hivex pev
local ver ntoskrnl_exe=$(find_file_ignore_case $os_dir/Windows/System32/ntoskrnl.exe)
ver="$(peres -v "$dll" | grep 'Product Version:' | awk '{print $NF}')" hive=$(find_file_ignore_case $os_dir/Windows/System32/config/SOFTWARE)
echo "Version: $ver" >&2 IFS=. read -r nt_ver_major nt_ver_minor _ rev_ver _ \
IFS=. read -r nt_ver_major nt_ver_minor build_ver rev_ver _ < <(echo "$ver") < <(peres -v "$ntoskrnl_exe" | grep 'Product Version:' | awk '{print $NF}')
nt_ver="$nt_ver_major.$nt_ver_minor" nt_ver="$nt_ver_major.$nt_ver_minor"
apk del pev # win10 22h2 19045 的 exe/dll 版本还是 19041 的,因此要从注册表获取
build_ver=$(hivexget $hive 'Microsoft\Windows NT\CurrentVersion' CurrentBuildNumber)
echo "Version: $nt_ver_major.$nt_ver_minor.$build_ver.$rev_ver" >&2
apk del hivex pev
} }
is_elts() { is_elts() {
@ -934,11 +946,15 @@ unix2dos() {
} }
insert_into_file() { insert_into_file() {
file=$1 local file=$1
location=$2 local location=$2
regex_to_find=$3 local regex_to_find=$3
shift 3 shift 3
if ! [ -f "$file" ]; then
error_and_exit "File not found: $file"
fi
# 默认 grep -E # 默认 grep -E
if [ $# -eq 0 ]; then if [ $# -eq 0 ]; then
set -- -E set -- -E
@ -1614,9 +1630,9 @@ install_nixos() {
fi fi
# 备用方案 # 备用方案
# 1. 从 https://mirror.nju.edu.cn/nix-channels/nixos-25.05/nixexprs.tar.xz 获取 # 1. 从 https://mirror.nju.edu.cn/nix-channels/nixos-25.11/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.11/pkgs/tools/package-management/nix/default.nix
# https://github.com/NixOS/nixpkgs/blob/nixos-25.05/nixos/modules/installer/tools/nix-fallback-paths.nix # https://github.com/NixOS/nixpkgs/blob/nixos-25.11/nixos/modules/installer/tools/nix-fallback-paths.nix
# 2. 安装最新版 nix添加 nixos channel 后获取 # 2. 安装最新版 nix添加 nixos channel 后获取
# nix eval -f '<nixpkgs>' --raw 'nixVersions.stable.version' --extra-experimental-features nix-command # nix eval -f '<nixpkgs>' --raw 'nixVersions.stable.version' --extra-experimental-features nix-command
@ -1854,6 +1870,8 @@ add_frpc_systemd_service_if_need() {
frpc_url=$(get_frpc_url linux) frpc_url=$(get_frpc_url linux)
basename=$(echo "$frpc_url" | awk -F/ '{print $NF}' | sed 's/\.tar\.gz//') basename=$(echo "$frpc_url" | awk -F/ '{print $NF}' | sed 's/\.tar\.gz//')
download "$frpc_url" "$os_dir/frpc.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" "$basename/frpc" -O >"$os_dir/usr/local/bin/frpc"
rm -f "$os_dir/frpc.tar.gz" rm -f "$os_dir/frpc.tar.gz"
chmod a+x "$os_dir/usr/local/bin/frpc" chmod a+x "$os_dir/usr/local/bin/frpc"
@ -2274,8 +2292,8 @@ aria2c() {
apk add coreutils apk add coreutils
fi fi
# 指定 bt 种子时没有链接,因此忽略错误 # 显示 url
echo "$@" | grep -oE '(http|https|magnet):[^ ]*' || true show_url_in_args "$@" >&2
# 下载 tracker # 下载 tracker
# 在 sub shell 里面无法保存变量,因此写入到文件 # 在 sub shell 里面无法保存变量,因此写入到文件
@ -2440,8 +2458,8 @@ create_part() {
# shellcheck disable=SC2154 # shellcheck disable=SC2154
if [ "$distro" = windows ]; then if [ "$distro" = windows ]; then
if ! size_bytes=$(get_link_file_size "$iso"); then if ! size_bytes=$(get_link_file_size "$iso"); then
# 默认值最大的iso 23h2 假设 7g # 默认值,目前最大的 iso 小于 8g
size_bytes=$((7 * 1024 * 1024 * 1024)) size_bytes=$((8 * 1024 * 1024 * 1024))
fi fi
# 按iso容量计算分区大小 # 按iso容量计算分区大小
@ -2738,14 +2756,6 @@ mount_pseudo_fs() {
fi 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() { create_cloud_init_network_config() {
ci_file=$1 ci_file=$1
recognize_static6=${2:-true} recognize_static6=${2:-true}
@ -2757,7 +2767,7 @@ create_cloud_init_network_config() {
mkdir -p "$(dirname "$ci_file")" mkdir -p "$(dirname "$ci_file")"
touch "$ci_file" touch "$ci_file"
apk add "$(get_yq_name)" apk add yq-go
need_set_dns4=false need_set_dns4=false
need_set_dns6=false need_set_dns6=false
@ -2871,7 +2881,7 @@ create_cloud_init_network_config() {
yq -i "del(.network.config[$config_id] | select(has(\"address\") | not))" $ci_file yq -i "del(.network.config[$config_id] | select(has(\"address\") | not))" $ci_file
fi fi
apk del "$(get_yq_name)" apk del yq-go
# 查看文件 # 查看文件
info "Cloud-init network config" info "Cloud-init network config"
@ -3234,7 +3244,7 @@ remove_cloud_init() {
# disable 会出现一堆提示信息,也无法 disable # disable 会出现一堆提示信息,也无法 disable
for unit in $( for unit in $(
chroot $os_dir systemctl list-unit-files | chroot $os_dir systemctl list-unit-files |
grep -E '^(cloud-init-.*|cloud-config|cloud-final)\.(service|socket)' | grep enabled | awk '{print $1}' grep -E '^(cloud-init|cloud-init-.*|cloud-config|cloud-final)\.(service|socket)' | grep enabled | awk '{print $1}'
); do ); do
# 服务不存在时会报错 # 服务不存在时会报错
if chroot $os_dir systemctl -q is-enabled "$unit"; then if chroot $os_dir systemctl -q is-enabled "$unit"; then
@ -3251,7 +3261,7 @@ remove_cloud_init() {
;; ;;
zypper) zypper)
# 加上 -u 才会删除依赖 # 加上 -u 才会删除依赖
chroot $os_dir zypper remove -y -u cloud-init chroot $os_dir zypper remove -y -u cloud-init cloud-init-config-suse
;; ;;
apt-get) apt-get)
# ubuntu 25.04 开始有 cloud-init-base # ubuntu 25.04 开始有 cloud-init-base
@ -3364,6 +3374,19 @@ EOF
create_network_manager_config /net.cfg "$os_dir" create_network_manager_config /net.cfg "$os_dir"
rm /net.cfg rm /net.cfg
# TODO: fedora 43 eol 后删除
# 删除 cloud-init 会删除依赖包 netcat
# 但是删除 netcat 时会报错
# 因此保留 netcat 包
# >>> Running %preun scriptlet: netcat-0:1.229-3.fc43.x86_64
# >>> Error in %preun scriptlet: netcat-0:1.229-3.fc43.x86_64
# >>> Scriptlet output:
# >>> failed to create admindir: No such file or directory
# >>> [RPM] %preun(netcat-1.229-3.fc43.x86_64) scriptlet failed, exit status 2
# >>> [RPM] netcat-1.229-3.fc43.x86_64: erase failed
if [ "$distro" = fedora ] && [ "$releasever" = 43 ]; then
chroot $os_dir dnf mark user netcat -y
fi
remove_cloud_init $os_dir remove_cloud_init $os_dir
disable_selinux $os_dir disable_selinux $os_dir
@ -3627,24 +3650,35 @@ EOF
fi fi
# rpm -qi 不支持通配符 # rpm -qi 不支持通配符
installed_kernel=$(chroot $os_dir rpm -qa 'kernel-*' --qf '%{NAME}\n' | grep -v firmware) origin_kernel=$(chroot $os_dir rpm -qa 'kernel-*' --qf '%{NAME}\n' | grep -v firmware)
if ! [ "$(echo "$installed_kernel" | wc -l)" -eq 1 ]; then if ! [ "$(echo "$origin_kernel" | wc -l)" -eq 1 ]; then
error_and_exit "Unexpected kernel installed: $installed_kernel" error_and_exit "Unexpected kernel installed: $origin_kernel"
fi fi
# 能同时装 kernel-default-base 和 kernel-default # 16.0 能同时装 kernel-default-base 和 kernel-default
# tw 不能同时装 kernel-default-base 和 kernel-default
# 因此需要添加 --force-resolution 自动删除 kernel-default-base # 因此需要添加 --force-resolution 自动删除 kernel-default-base
if ! [ "$installed_kernel" = "$target_kernel" ]; then if ! [ "$origin_kernel" = "$target_kernel" ]; then
# x86 必须设置一个密码否则报错arm 没有这个问题 # x86 必须设置一个密码否则报错arm 没有这个问题
# Failed to get root password hash # Failed to get root password hash
# Failed to import /etc/uefi/certs/76B6A6A0.crt # 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 # 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 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 echo "root:$(mkpasswd '')" | chroot $os_dir chpasswd -e
fi
# 安装新内核
chroot $os_dir zypper install -y --force-resolution $target_kernel 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 chroot $os_dir passwd -d root
else
chroot $os_dir zypper install -y --force-resolution $target_kernel
fi fi
fi fi
@ -3764,7 +3798,7 @@ modify_os_on_disk() {
# shellcheck disable=SC1090 # shellcheck disable=SC1090
# find_file_ignore_case 也在这个文件里面 # find_file_ignore_case 也在这个文件里面
. <(wget -O- $confhome/windows-driver-utils.sh) . <(wget -O- $confhome/windows-driver-utils.sh)
if ntoskrnl_exe=$(find_file_ignore_case /os/Windows/System32/ntoskrnl.exe 2>/dev/null); then if find_file_ignore_case /os/Windows/System32/ntoskrnl.exe >/dev/null 2>&1; then
# 其他地方会用到 # 其他地方会用到
is_windows() { true; } is_windows() { true; }
# 重新挂载为读写、忽略大小写 # 重新挂载为读写、忽略大小写
@ -3785,7 +3819,7 @@ modify_os_on_disk() {
mount -t ntfs3 -o nocase,rw,force /dev/$part /os mount -t ntfs3 -o nocase,rw,force /dev/$part /os
fi fi
# 获取版本号,其他地方会用到 # 获取版本号,其他地方会用到
get_windows_version_from_dll "$ntoskrnl_exe" get_windows_version_from_windows_drive /os
modify_windows /os modify_windows /os
return return
fi fi
@ -4400,7 +4434,7 @@ install_qcow_by_copy() {
fi fi
# el7 yum 可能会使用 ipv6即使没有 ipv6 网络 # el7 yum 可能会使用 ipv6即使没有 ipv6 网络
if [ "$(cat /dev/netconf/eth*/ipv6_has_internet | sort -u)" = 0 ]; then if [ "$(cat /dev/netconf/*/ipv6_has_internet | sort -u)" = 0 ]; then
echo 'ip_resolve=4' >>/os/etc/yum.conf echo 'ip_resolve=4' >>/os/etc/yum.conf
fi fi
@ -5704,8 +5738,7 @@ install_windows() {
# 3. 是否支持 sha256 # 3. 是否支持 sha256
# 4. Installation Type # 4. Installation Type
wimmount "$iso_install_wim" "$image_index" /wim/ wimmount "$iso_install_wim" "$image_index" /wim/
ntoskrnl_exe=$(find_file_ignore_case /wim/Windows/System32/ntoskrnl.exe) get_windows_version_from_windows_drive /wim
get_windows_version_from_dll "$ntoskrnl_exe"
windows_type=$(get_windows_type_from_windows_drive /wim) windows_type=$(get_windows_type_from_windows_drive /wim)
{ {
find_file_ignore_case /wim/Windows/System32/sacsess.exe && has_sac=true || has_sac=false find_file_ignore_case /wim/Windows/System32/sacsess.exe && has_sac=true || has_sac=false
@ -5807,6 +5840,7 @@ install_windows() {
# 用注册表无法绕过 # 用注册表无法绕过
# https://github.com/pbatard/rufus/issues/1990 # https://github.com/pbatard/rufus/issues/1990
# https://learn.microsoft.com/windows/iot/iot-enterprise/Hardware/System_Requirements # https://learn.microsoft.com/windows/iot/iot-enterprise/Hardware/System_Requirements
# win11 旧版本安装程序24h2之前无法用 setup.exe /product server 跳过 cpu 核数限制因此在xml里解除限制
if [ "$product_ver" = "11" ] && [ "$(nproc)" -le 1 ]; then if [ "$product_ver" = "11" ] && [ "$(nproc)" -le 1 ]; then
wiminfo "$install_wim" "$image_index" --image-property WINDOWS/INSTALLATIONTYPE=Server wiminfo "$install_wim" "$image_index" --image-property WINDOWS/INSTALLATIONTYPE=Server
fi fi
@ -5946,28 +5980,43 @@ install_windows() {
esac esac
) )
file=$( url=$(
case "$product_ver" in case "$product_ver" in
'7' | '2008 r2') $support_sha256 && '7' | '2008 r2')
# 现在官网只有 25.0
# 25.0 比 24.5 只更新了 ProSet 软件,驱动相同 # 25.0 比 24.5 只更新了 ProSet 软件,驱动相同
echo 18713/eng/prowin${arch_intel}legacy.exe || # 25.0 有部分文件是 sha256 签名 # 25.0 有部分文件是 sha256 签名
echo 29323/eng/prowin${arch_intel}legacy.exe ;; # 24.3 sha1 签名 # 24.3 全部文件是 sha1 签名
# https://web.archive.org/web/20250405130938/https://www.intel.com/content/www/us/en/download/15590/29323/intel-network-adapter-driver-for-windows-7-final-release.html
echo https://downloadmirror.intel.com/18713/eng/prowin${arch_intel}legacy.exe
;;
'8' | '8.1')
# 之前有 Intel® Network Adapter Driver for Windows 8* - Final Release ,版本 22.7.1 # 之前有 Intel® Network Adapter Driver for Windows 8* - Final Release ,版本 22.7.1
# 但已被删除,原因不明 # 但已被删除,原因不明
# https://web.archive.org/web/20250501043104/https://www.intel.com/content/www/us/en/download/16765/intel-network-adapter-driver-for-windows-8-final-release.html # https://web.archive.org/web/20250501043104/https://www.intel.com/content/www/us/en/download/16765/intel-network-adapter-driver-for-windows-8-final-release.html
# 27.8 有 NDIS63 文件夹,意味着支持 Windows 8 # 27.8 有 NDIS63 文件夹,意味着支持 Windows 8
# 27.8 相比 22.7.1,可能有些老设备不支持了,但我们不管了 # 27.8 相比 22.7.1,可能有些老设备不支持了,但我们不管了
'8' | '8.1') echo 764813/Wired_driver_27.8_${arch_intel}.zip ;; echo https://downloadmirror.intel.com/764813/Wired_driver_27.8_${arch_intel}.zip
'2012' | '2012 r2') echo 772074/Wired_driver_28.0_${arch_intel}.zip ;; ;;
'2012' | '2012 r2')
echo https://downloadmirror.intel.com/772074/Wired_driver_28.0_${arch_intel}.zip
;;
# 2016 2019 2022 2025 win10 win11
*) case "${arch_intel}" in *) case "${arch_intel}" in
32) echo 849483/Wired_driver_30.0.1_${arch_intel}.zip ;; 32)
x64) echo 864508/Wired_driver_30.4_${arch_intel}.zip ;; echo https://downloadmirror.intel.com/849483/Wired_driver_30.0.1_${arch_intel}.zip
;;
x64)
# intel 禁止了 wget 下载网页
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 ;; esac ;;
esac esac
) )
# 注意 intel 禁止了 aria2 下载 # 注意 intel 禁止了 aria2 下载
download https://downloadmirror.intel.com/$file $drv/intel.zip download "$url" $drv/intel.zip
# inf 可能是 UTF-16 LE因此用 rg 搜索 # inf 可能是 UTF-16 LE因此用 rg 搜索
# 用 busybox unzip 解压 win10 驱动时,路径和文件名会粘在一起 # 用 busybox unzip 解压 win10 驱动时,路径和文件名会粘在一起
@ -6569,12 +6618,17 @@ EOF
done done
if ! $is_gen11 && [ "$build_ver" -ge 19041 ]; then if ! $is_gen11 && [ "$build_ver" -ge 19041 ]; then
url=https://downloadmirror.intel.com/865363/SetupRST.exe # RST v20 # RST v20
local page=https://www.intel.com/content/www/us/en/download/849936.html
elif [ "$build_ver" -ge 15063 ]; then elif [ "$build_ver" -ge 15063 ]; then
url=https://downloadmirror.intel.com/849934/SetupRST.exe # RST v19 # RST v19
local page=https://www.intel.com/content/www/us/en/download/849933.html
else else
error_and_exit "can't find suitable vmd driver" error_and_exit "can't find suitable vmd driver"
fi fi
local url
url=$(wget -U curl/7.54.1 "$page" -O- |
grep -Eio -m1 "\"https://.+/SetupRST\.exe\"" | tr -d '"' | grep .)
# 注意 intel 禁止了 aria2 下载 # 注意 intel 禁止了 aria2 下载
download $url $drv/SetupRST.exe download $url $drv/SetupRST.exe