mirror of
https://github.com/bin456789/reinstall.git
synced 2025-12-10 15:37:43 +08:00
Compare commits
44 Commits
97779b6f6e
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| e60a8d0de2 | |||
| 2a561f0d8c | |||
| 586eb5dee1 | |||
| c94f334663 | |||
| bd5e118570 | |||
| 78ba0690f9 | |||
| 9e0968eabd | |||
| 3263ea3875 | |||
| 7c19559d86 | |||
| 8b838f8871 | |||
| 5bf00edeed | |||
| 85637edc5b | |||
| baa430eb10 | |||
| 66f3173c7b | |||
| af84ac0b3c | |||
| 57a88a6bd9 | |||
| 24a4446a02 | |||
| 780e1a694f | |||
| 43ba86076f | |||
| f22cda1f10 | |||
| 28e10128ff | |||
| 974d5712f0 | |||
| 845fa66e03 | |||
| 48823b4101 | |||
| d212eb793c | |||
| aa1fc741fa | |||
| 74665b65cc | |||
| 6708c77c63 | |||
| 1afc1a0022 | |||
| cdf09d017f | |||
| 8d55af091d | |||
| 8689c45b07 | |||
| ce8a315a2e | |||
| cf6b4c226d | |||
| b098c0cabd | |||
| 2a0690a395 | |||
| 30a3616bf8 | |||
| df2bda09dc | |||
| 38a5cc3940 | |||
| c7e156dae4 | |||
| edcefc3e8c | |||
| 29023e0f44 | |||
| 8b424e8091 | |||
| 9521e84703 |
15
.github/ISSUE_TEMPLATE/bug_report.md
vendored
15
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@ -7,10 +7,13 @@ assignees: ''
|
||||
|
||||
---
|
||||
|
||||
原来的系统:
|
||||
要安装的系统:
|
||||
遇到的问题:截图或者登录 SSH 获取日志 /reinstall.log
|
||||
原来的系统 (Original system):
|
||||
|
||||
Original system:
|
||||
System to be installed:
|
||||
Issues encountered: Screenshot or log in via SSH to get the logs from /reinstall.log
|
||||
要安装的系统 (System to be installed):
|
||||
|
||||
遇到的问题 (Issue):
|
||||
|
||||
<!--
|
||||
请上传截图或者报错内容,注意删除 IP 地址和密码
|
||||
(Please Upload Screenshot or error message. Be sure to delete the IP address and password)
|
||||
-->
|
||||
|
||||
19
.github/workflows/run_reinstall.yml
vendored
19
.github/workflows/run_reinstall.yml
vendored
@ -21,18 +21,19 @@ jobs:
|
||||
git config --global core.autocrlf false
|
||||
- uses: actions/checkout@v4
|
||||
- run: |
|
||||
${{ matrix.command }} centos
|
||||
${{ matrix.command }} almalinux 8
|
||||
${{ matrix.command }} rocky 9
|
||||
${{ matrix.command }} fedora
|
||||
# ${{ matrix.command }} centos
|
||||
${{ matrix.command }} almalinux
|
||||
# ${{ matrix.command }} rocky
|
||||
# ${{ matrix.command }} fedora
|
||||
# ${{ matrix.command }} oracle
|
||||
${{ matrix.command }} ubuntu
|
||||
${{ matrix.command }} debian
|
||||
${{ matrix.command }} debian --ci
|
||||
${{ matrix.command }} kali
|
||||
${{ matrix.command }} alpine
|
||||
${{ matrix.command }} opensuse
|
||||
${{ matrix.command }} arch
|
||||
${{ matrix.command }} gentoo
|
||||
# ${{ matrix.command }} kali
|
||||
# ${{ matrix.command }} alpine
|
||||
# ${{ matrix.command }} opensuse
|
||||
# ${{ matrix.command }} arch
|
||||
# ${{ matrix.command }} gentoo
|
||||
|
||||
${{ matrix.command }} netboot.xyz
|
||||
${{ matrix.command }} dd --img=https://download.opensuse.org/tumbleweed/appliances/openSUSE-MicroOS.x86_64-SelfInstall.raw.xz
|
||||
|
||||
252
README.en.md
252
README.en.md
@ -5,24 +5,39 @@
|
||||
[](https://app.codacy.com/gh/bin456789/reinstall/dashboard)
|
||||
[](https://www.codefactor.io/repository/github/bin456789/reinstall)
|
||||
[](https://github.com/XAMPPRocky/tokei_rs)
|
||||
[](https://t.me/reinstall_os)
|
||||
[](https://github.com/sponsors/bin456789)
|
||||
|
||||
One-Click Script to Reinstall System [中文](README.md)
|
||||
One-Click system reinstallation script for VPS [中文](README.md)
|
||||
|
||||
[](https://github.com/sponsors/bin456789)
|
||||
## Introduction
|
||||
|
||||
## Highlights
|
||||
|
||||
- One-click Linux installation: Supports 19 common distributions.
|
||||
- One-click Windows installation: Uses the official ISO for installation instead of custom images. The script can automatically retrieves the ISO link and installs common drivers like `Virtio`.
|
||||
- Supports installation in any direction, i.e., `Linux to Linux`, `Linux to Windows`, `Windows to Windows`, `Windows to Linux`
|
||||
- No need to input IP parameters; automatically recognizes dynamic and static IPs, supports `/32`, `/128`, `gateway outside subnet`, `IPv6 only`, `dual NIC`
|
||||
- One-click reinstallation to Linux: Supports 19 common distributions.
|
||||
- One-click reinstallation to Windows: Uses the official original ISO instead of custom images. The script can automatically fetch the ISO link and installs public cloud drivers like `VirtIO`.
|
||||
- Supports reinstallation in any direction, i.e., `Linux to Linux`, `Linux to Windows`, `Windows to Windows`, `Windows to Linux`
|
||||
- Automatically configures IP and intelligently sets it as static or dynamic. Supports `/32`, `/128`, `gateway outside subnet`, `IPv6 only`, `IPv4/IPv6 on different NIC`
|
||||
- Specially optimized for low-spec servers, requires less memory than the official netboot
|
||||
- Uses partition table ID to identify hard drives throughout the process, ensuring no wrong disk is written
|
||||
- Supports BIOS and EFI boot, and ARM Server
|
||||
- No homemades image included, all resources are obtained in real-time from mirror sites
|
||||
|
||||
If this helped you, you can buy me a milk tea.
|
||||
[](https://github.com/sponsors/bin456789)
|
||||
|
||||
[](https://github.com/sponsors/bin456789)
|
||||
|
||||
### Feedback
|
||||
|
||||
[](https://github.com/bin456789/reinstall/issues)
|
||||
[](https://t.me/reinstall_os)
|
||||
|
||||
## Quick Start
|
||||
|
||||
- [Download](#download-current-system-is--linux)
|
||||
- [Feature 1. One-click reinstallation to Linux](#feature-1-install--linux)
|
||||
- [Feature 2. One-click DD Raw image to hard disk](#feature-2-dd-raw-image-to-hard-disk)
|
||||
- [Feature 3. One-click reboot to Alpine Live OS in-memory system](#feature-3-reboot-to--alpine-live-os-ram-os)
|
||||
- [Feature 4. One-click reboot to netboot.xyz](#feature-4-reboot-to--netbootxyz)
|
||||
- [Feature 5. One-click reinstallation to Windows](#feature-5-install--windows-iso)
|
||||
|
||||
## System Requirements
|
||||
|
||||
The original system can be any system listed in the table.
|
||||
@ -31,22 +46,22 @@ The system requirements for the target system are as follows:
|
||||
|
||||
| System | Version | Memory | Disk |
|
||||
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------- | --------- | ---------------- |
|
||||
| <img width="16" height="16" src="https://www.alpinelinux.org/alpine-logo.ico" /> Alpine | 3.19, 3.20, 3.21, 3.22 | 256 MB | 1 GB |
|
||||
| <img width="16" height="16" src="https://www.debian.org/favicon.ico" /> Debian | 9, 10, 11, 12 | 256 MB | 1 ~ 1.5 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://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.04 | 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 |
|
||||
| <img width="16" height="16" src="https://img.alicdn.com/imgextra/i1/O1CN01oJnJZg1yK4RzI4Rx2_!!6000000006559-2-tps-118-118.png" /> Anolis | 7, 8, 23 | 512 MB \* | 5 GB |
|
||||
| <img width="16" height="16" src="https://www.redhat.com/favicon.ico" /> RHEL <img width="16" height="16" src="https://almalinux.org/fav/favicon.ico" /> AlmaLinux <img width="16" height="16" src="https://rockylinux.org/favicon.png" /> Rocky <img width="16" height="16" src="https://www.oracle.com/asset/web/favicons/favicon-32.png" /> Oracle | 8, 9, 10 (if released) | 512 MB \* | 5 GB |
|
||||
| <img width="16" height="16" src="https://www.redhat.com/favicon.ico" /> RHEL <img width="16" height="16" src="https://almalinux.org/fav/favicon.ico" /> AlmaLinux <img width="16" height="16" src="https://rockylinux.org/favicon.png" /> Rocky <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://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://www.openeuler.org/favicon.ico" /> openEuler | 20.03 LTS - 24.03 LTS, 25.03 | 512 MB \* | 5 GB |
|
||||
| <img width="16" height="16" src="https://static.opensuse.org/favicon.ico" /> openSUSE | Leap 15.6, 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://fedoraproject.org/favicon.ico" /> Fedora | 42, 43 | 512 MB \* | 5 GB |
|
||||
| <img width="16" height="16" src="https://www.openeuler.org/favicon.ico" /> openEuler | 20.03 LTS - 24.03 LTS, 25.09 | 512 MB \* | 5 GB |
|
||||
| <img width="16" height="16" src="https://static.opensuse.org/favicon.ico" /> openSUSE | Leap 15.6, 16.0, Tumbleweed (Rolling) | 512 MB \* | 5 GB |
|
||||
| <img width="16" height="16" src="https://nixos.org/favicon.svg" /> NixOS | 25.11 | 512 MB | 5 GB |
|
||||
| <img width="16" height="16" src="https://archlinux.org/static/favicon.png" /> Arch | Rolling | 512 MB | 5 GB |
|
||||
| <img width="16" height="16" src="https://www.gentoo.org/assets/img/logo/gentoo-g.png" /> Gentoo | Rolling | 512 MB | 5 GB |
|
||||
| <img width="16" height="16" src="https://aosc.io/assets/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://aosc.io/distros/aosc-os.svg" /> AOSC OS | Rolling | 512 MB | 5 GB |
|
||||
| <img width="16" height="16" src="https://www.fnnas.com/favicon.ico" /> fnOS | 1 | 512 MB | 8 GB |
|
||||
| <img width="16" height="16" src="https://blogs.windows.com/wp-content/uploads/prod/2022/09/cropped-Windows11IconTransparent512-32x32.png" /> Windows (DD) | Any | 512 MB | Depends on image |
|
||||
| <img width="16" height="16" src="https://blogs.windows.com/wp-content/uploads/prod/2022/09/cropped-Windows11IconTransparent512-32x32.png" /> Windows (ISO) | Vista, 7, 8.x (Server 2008 - 2012 R2) | 512 MB | 25 GB |
|
||||
| <img width="16" height="16" src="https://blogs.windows.com/wp-content/uploads/prod/2022/09/cropped-Windows11IconTransparent512-32x32.png" /> Windows (ISO) | 10, 11 (Server 2016 - 2025) | 1 GB | 25 GB |
|
||||
@ -56,6 +71,13 @@ The system requirements for the target system are as follows:
|
||||
^ Indicates requiring either 256 MB memory + 1.5 GB disk, or 512 MB memory + 1 GB disk
|
||||
|
||||
> [!WARNING]
|
||||
>
|
||||
> In theory it also supports dedicated servers and PCs
|
||||
>
|
||||
> but if you can use IPMI or a USB drive, this script is not recommended.
|
||||
|
||||
> [!WARNING]
|
||||
>
|
||||
> ❌ This script does not support OpenVZ or LXC virtual machines.
|
||||
>
|
||||
> Please use <https://github.com/LloydAsp/OsMutation> instead.
|
||||
@ -65,13 +87,13 @@ The system requirements for the target system are as follows:
|
||||
For server outside China:
|
||||
|
||||
```bash
|
||||
curl -O https://raw.githubusercontent.com/bin456789/reinstall/main/reinstall.sh || wget -O reinstall.sh $_
|
||||
curl -O https://raw.githubusercontent.com/bin456789/reinstall/main/reinstall.sh || wget -O ${_##*/} $_
|
||||
```
|
||||
|
||||
For server inside China:
|
||||
|
||||
```bash
|
||||
curl -O https://cnb.cool/bin456789/reinstall/-/git/raw/main/reinstall.sh || wget -O reinstall.sh $_
|
||||
curl -O https://cnb.cool/bin456789/reinstall/-/git/raw/main/reinstall.sh || wget -O ${_##*/} $_
|
||||
```
|
||||
|
||||
## Download (Current system is <img width="20" height="20" src="https://blogs.windows.com/wp-content/uploads/prod/2022/09/cropped-Windows11IconTransparent512-32x32.png" /> Windows)
|
||||
@ -117,7 +139,13 @@ certutil -urlcache -f -split https://cnb.cool/bin456789/reinstall/-/git/raw/main
|
||||
|
||||
### Feature 1: Install <img width="16" height="16" src="https://www.kernel.org/theme/images/logos/favicon.png" /> Linux
|
||||
|
||||
- The username is `root` with a default password of `123@@@`.
|
||||
> [!CAUTION]
|
||||
>
|
||||
> This feature will erase **the entire hard disk** of the current system (including other partitions)!
|
||||
>
|
||||
> Data is priceless — please think twice before proceeding!
|
||||
|
||||
- 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.
|
||||
- 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.
|
||||
@ -127,47 +155,42 @@ certutil -urlcache -f -split https://cnb.cool/bin456789/reinstall/-/git/raw/main
|
||||
```bash
|
||||
bash reinstall.sh anolis 7|8|23
|
||||
rocky 8|9|10
|
||||
oracle 8|9
|
||||
oracle 8|9|10
|
||||
almalinux 8|9|10
|
||||
opencloudos 8|9|23
|
||||
centos 9|10
|
||||
fedora 41|42
|
||||
nixos 25.05
|
||||
debian 9|10|11|12
|
||||
opensuse 15.6|tumbleweed
|
||||
alpine 3.19|3.20|3.21|3.22
|
||||
openeuler 20.03|22.03|24.03|25.03
|
||||
ubuntu 16.04|18.04|20.04|22.04|24.04|25.04 [--minimal]
|
||||
fnos 1
|
||||
nixos 25.11
|
||||
fedora 42|43
|
||||
debian 9|10|11|12|13
|
||||
alpine 3.20|3.21|3.22|3.23
|
||||
opensuse 15.6|16.0|tumbleweed
|
||||
openeuler 20.03|22.03|24.03|25.09
|
||||
ubuntu 16.04|18.04|20.04|22.04|24.04|25.10 [--minimal]
|
||||
kali
|
||||
arch
|
||||
gentoo
|
||||
aosc
|
||||
fnos
|
||||
redhat --img="http://access.cdn.redhat.com/xxx.qcow2"
|
||||
```
|
||||
|
||||
#### Optional Parameters
|
||||
|
||||
- `--password PASSWORD` Set the password
|
||||
- `--ssh-key KEY` Set up SSH login public key, supports these formats. When using public key, password is empty.
|
||||
- `--ssh-key "ssh-rsa ..."`
|
||||
- `--ssh-key "ssh-ed25519 ..."`
|
||||
- `--ssh-key "ecdsa-sha2-nistp256/384/521 ..."`
|
||||
- `--ssh-key http://path/to/public_key`
|
||||
- `--ssh-key github:your_username`
|
||||
- `--ssh-key gitlab:your_username`
|
||||
- `--ssh-key /path/to/public_key`
|
||||
- `--ssh-key C:\path\to\public_key`
|
||||
- `--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)
|
||||
- `--web-port PORT` Change the Web port (for log observation during installation)
|
||||
- `--frpc-toml /path/to/frpc.toml` Add frpc for intranet tunneling
|
||||
- `--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).
|
||||
- `--web-port PORT` Change the Web port (for log observation during installation only)
|
||||
- `--frpc-toml PATH` Add frpc for intranet tunneling. Parameter can be local filepath or HTTP URL
|
||||
- `--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]
|
||||
> 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).
|
||||
> <br />Even if errors occur during the installation process, you can still install to Alpine via SSH by running `/trans.sh alpine`
|
||||
> Can monitor the progress through various methods (SSH, HTTP 80 port, VNC from server provider, serial console).
|
||||
>
|
||||
> 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>
|
||||
|
||||
@ -201,9 +224,15 @@ bash reinstall.sh ubuntu --installer
|
||||
|
||||
</details>
|
||||
|
||||
### Feature 2: DD
|
||||
### Feature 2: DD RAW image to hard disk
|
||||
|
||||
- Supports `raw` and `vhd` image formats (either uncompressed or compressed as `.gz`, `.xz`, `.zst`, `.tar`, `.tar.gz`, `.tar.xz`, `.tar.zst`).
|
||||
> [!CAUTION]
|
||||
>
|
||||
> This feature will erase **the entire hard disk** of the current system (including other partitions)!
|
||||
>
|
||||
> Data is priceless — please think twice before proceeding!
|
||||
|
||||
- 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 Linux image, will **NOT** modify any contents of the image.
|
||||
|
||||
@ -217,42 +246,49 @@ bash reinstall.sh dd --img "https://example.com/xxx.xz"
|
||||
- `--rdp-port PORT` Change RDP port (DD Windows only)
|
||||
- `--ssh-port PORT` Change SSH 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)
|
||||
- `--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.
|
||||
- `--frpc-toml PATH` Add frpc for intranet tunneling (DD Windows only). Parameter can be local filepath or HTTP URL
|
||||
- `--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]
|
||||
>
|
||||
> 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)
|
||||
|
||||
- You can use SSH to backup/restore disk, manually perform DD operations, modify partitions, and manually install Alpine, Arch, Gentoo, and other systems.
|
||||
- Username `root`, Default password `123@@@`
|
||||
- If manual operations do not damage the original system, rebooting will return to the original system.
|
||||
- You can use SSH to backup/restore disk, manually perform DD operations, partition modifications, manual Alpine installation, and other operations.
|
||||
- Username `root`. The script prompts for a password. If left blank, a random one is generated.
|
||||
|
||||
> [!TIP]
|
||||
>
|
||||
> Although the script being run is `reinstall`, this feature **does not** delete any data or perform an automatic reinstallation; manual user operation is required.
|
||||
|
||||
> If the user does not damage the original system during manual operation, rebooting will return to the original system.
|
||||
|
||||
```bash
|
||||
bash reinstall.sh alpine --hold=1
|
||||
bash reinstall.sh alpine --hold 1
|
||||
```
|
||||
|
||||
#### Optional Parameters
|
||||
|
||||
- `--password PASSWORD` Set password
|
||||
- `--ssh-port PORT` Change SSH port
|
||||
- `--ssh-key KEY` Set up SSH login public key, supports these formats. When using public key, password is empty.
|
||||
- `--ssh-key "ssh-rsa ..."`
|
||||
- `--ssh-key "ssh-ed25519 ..."`
|
||||
- `--ssh-key "ecdsa-sha2-nistp256/384/521 ..."`
|
||||
- `--ssh-key http://path/to/public_key`
|
||||
- `--ssh-key github:your_username`
|
||||
- `--ssh-key gitlab:your_username`
|
||||
- `--ssh-key /path/to/public_key`
|
||||
- `--ssh-key C:\path\to\public_key`
|
||||
- `--frpc-toml /path/to/frpc.toml` Add frpc for intranet tunneling
|
||||
- `--ssh-key KEY` Set up SSH login public key, [formatted as follows](#--ssh-key). When using public key, password is empty.
|
||||
- `--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
|
||||
|
||||
- Can manually install [more systems](https://github.com/netbootxyz/netboot.xyz?tab=readme-ov-file#what-operating-systems-are-currently-available-on-netbootxyz) using vendor backend VNC.
|
||||
- If manual operations do not damage the original system, rebooting will return to the original system.
|
||||
|
||||
> [!TIP]
|
||||
>
|
||||
> Although the script being run is `reinstall`, this feature **does not** delete any data or perform an automatic reinstallation; manual user operation is required.
|
||||
|
||||
> If the user does not damage the original system during manual operation, rebooting will return to the original system.
|
||||
|
||||
```bash
|
||||
bash reinstall.sh netboot.xyz
|
||||
@ -264,10 +300,17 @@ bash reinstall.sh netboot.xyz
|
||||
|
||||

|
||||
|
||||
- Username `administrator`, Default password `123@@@`
|
||||
> [!CAUTION]
|
||||
>
|
||||
> This feature will erase **the entire hard disk** of the current system (including other partitions)!
|
||||
>
|
||||
> Data is priceless — please think twice before proceeding!
|
||||
|
||||
- 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`.
|
||||
- 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
|
||||
|
||||
@ -276,7 +319,7 @@ bash reinstall.sh netboot.xyz
|
||||
- Windows Server Essentials \*
|
||||
- Windows Server (Semi) Annual Channel \*
|
||||
- Hyper-V Server \*
|
||||
- Azure Stack HCI \*
|
||||
- Azure Local (Azure Stack HCI) \*
|
||||
|
||||
#### Method 1: Let the Script Automatically Search for ISO
|
||||
|
||||
@ -367,7 +410,6 @@ bash reinstall.sh windows \
|
||||
- <https://www.microsoft.com/software-download/windows11>
|
||||
- <https://www.microsoft.com/software-download/windows11arm64>
|
||||
- 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-iot-enterprise-ltsc-eval>
|
||||
- <https://www.microsoft.com/evalcenter/download-windows-server-2012-r2>
|
||||
@ -386,18 +428,19 @@ bash reinstall.sh windows \
|
||||
- `--password PASSWORD` Set Password
|
||||
- `--allow-ping` Configure Windows Firewall to Allow Ping Responses
|
||||
- `--rdp-port PORT` Change RDP port
|
||||
- `--ssh-port PORT` Change SSH port (for log observation during installation)
|
||||
- `--web-port PORT` Change Web port (for log observation during installation)
|
||||
- `--ssh-port PORT` Change SSH port (for log observation during installation only)
|
||||
- `--web-port PORT` Change Web port (for log observation during installation only)
|
||||
- `--add-driver INF_OR_DIR` Add additional driver, specifying .inf path, or the folder contains .inf file.
|
||||
- The driver must be downloaded locally first.
|
||||
- The driver must be downloaded to current system first.
|
||||
- This parameter can be set multiple times to add different driver.
|
||||
- `--frpc-toml /path/to/frpc.toml` Add frpc for intranet tunneling
|
||||
- `--hold 2` Allow SSH connections for modifying the disk content before rebooting into the official Windows installation program, with the disk mounted at `/os`.
|
||||
- `--frpc-toml PATH` Add frpc for intranet tunneling. Parameter can be local filepath or HTTP URL
|
||||
- `--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
|
||||
|
||||
- Virtio ([Virtio][virtio-virtio], [Alibaba Cloud][virtio-aliyun], [Tencent Cloud][virtio-qcloud], [GCP][virtio-gcp])
|
||||
- XEN ([~~XEN~~][xen-xen] (unsigned), [Citrix][xen-citrix], [AWS][xen-aws])
|
||||
- VirtIO ([Community][virtio-virtio], [Alibaba Cloud][virtio-aliyun], [Tencent Cloud][virtio-qcloud], [GCP][virtio-gcp])
|
||||
- XEN ([~~Community~~][xen-xen] (unsigned), [Citrix][xen-citrix], [AWS][xen-aws])
|
||||
- AWS ([ENA Network Adapter][aws-ena], [NVME Storage Controller][aws-nvme])
|
||||
- GCP ([gVNIC Network Adapter][gcp-gvnic], [GGA Display Adapter][gcp-gga])
|
||||
- Azure ([MANA Network Adapter][azure-mana])
|
||||
@ -421,7 +464,7 @@ bash reinstall.sh windows \
|
||||
[intel-nic-8.1]: https://www.intel.com/content/www/us/en/download/17479/intel-network-adapter-driver-for-windows-8-1.html
|
||||
[intel-nic-10]: https://www.intel.com/content/www/us/en/download/18293/intel-network-adapter-driver-for-windows-10.html
|
||||
[intel-nic-11]: https://www.intel.com/content/www/us/en/download/727998/intel-network-adapter-driver-for-microsoft-windows-11.html
|
||||
[intel-nic-2008-r2]: https://www.intel.com/content/www/us/en/download/15591/intel-network-adapter-driver-for-windows-server-2008-r2-final-release.html
|
||||
[intel-nic-2008-r2]: https://web.archive.org/web/20250501002542/https://www.intel.com/content/www/us/en/download/15591/intel-network-adapter-driver-for-windows-server-2008-r2-final-release.html
|
||||
[intel-nic-2012]: https://www.intel.com/content/www/us/en/download/16789/intel-network-adapter-driver-for-windows-server-2012.html
|
||||
[intel-nic-2012-r2]: https://www.intel.com/content/www/us/en/download/17480/intel-network-adapter-driver-for-windows-server-2012-r2.html
|
||||
[intel-nic-2016]: https://www.intel.com/content/www/us/en/download/18737/intel-network-adapter-driver-for-windows-server-2016.html
|
||||
@ -431,7 +474,7 @@ bash reinstall.sh windows \
|
||||
|
||||
#### How to Specify the Image Name `--image-name`
|
||||
|
||||
Typically, an ISO will contain multiple system versions, such as Home Edition and Professional Edition. The image name `--image-name` is used to specify the version to be installed, and it is case-insensitive when entered.
|
||||
An ISO usually contains multiple system editions, such as Home and Pro. Therefore, you need to use `--image-name` to specify the system edition (image name) to install, case-insensitive.
|
||||
|
||||
You can use tools like DISM, DISM++, or Wimlib to query the image names included in the ISO.
|
||||
|
||||
@ -454,15 +497,29 @@ 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.
|
||||
|
||||
> [!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]
|
||||
>
|
||||
> 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>.
|
||||
|
||||
> [!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:
|
||||
>
|
||||
> 1. Add the `--force-boot-mode bios` parameter. The script will install Windows in `BIOS boot + MBR partition table` mode.
|
||||
>
|
||||
> (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.
|
||||
|
||||
#### Considerations for Installing Windows on ARM
|
||||
|
||||
Most ARM machines support installing latest Windows 11.
|
||||
@ -492,10 +549,33 @@ Log in to the server using Remote Desktop, open Device Manager, locate the graph
|
||||
|
||||
</details>
|
||||
|
||||
## Discussion
|
||||
## Parameter Format
|
||||
|
||||
[](https://github.com/bin456789/reinstall/issues)
|
||||
[](https://t.me/reinstall_os)
|
||||
### --ssh-key
|
||||
|
||||
- `--ssh-key "ssh-rsa ..."`
|
||||
- `--ssh-key "ssh-ed25519 ..."`
|
||||
- `--ssh-key "ecdsa-sha2-nistp256/384/521 ..."`
|
||||
- `--ssh-key http://path/to/public_key`
|
||||
- `--ssh-key github:your_username`
|
||||
- `--ssh-key gitlab:your_username`
|
||||
- `--ssh-key /path/to/public_key`
|
||||
- `--ssh-key C:\path\to\public_key`
|
||||
|
||||
## How to Use an Old Version
|
||||
|
||||
According to the Law of Bug Conservation, fixing old bugs often introduces new ones.
|
||||
|
||||
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 version’s `commit_id` on the right side.
|
||||
|
||||
```bash
|
||||
commit_id=xxxxxxx
|
||||
curl -O https://raw.githubusercontent.com/bin456789/reinstall/$commit_id/reinstall.sh || wget -O ${_##*/} $_
|
||||
sed -i "/^confhome.*main$/s/main/$commit_id/" reinstall.sh
|
||||
bash reinstall.sh ...
|
||||
```
|
||||
|
||||
## How to Modify the Script for Your Own
|
||||
|
||||
@ -505,8 +585,6 @@ Log in to the server using Remote Desktop, open Device Manager, locate the graph
|
||||
|
||||
## Thanks
|
||||
|
||||
[](https://github.com/sponsors/bin456789)
|
||||
|
||||
Thanks to the following businesses for providing free servers.
|
||||
|
||||
[](https://www.oracle.com/cloud/)
|
||||
|
||||
250
README.md
250
README.md
@ -5,24 +5,39 @@
|
||||
[](https://app.codacy.com/gh/bin456789/reinstall/dashboard)
|
||||
[](https://www.codefactor.io/repository/github/bin456789/reinstall)
|
||||
[](https://github.com/XAMPPRocky/tokei_rs)
|
||||
[](https://t.me/reinstall_os)
|
||||
[](https://github.com/sponsors/bin456789)
|
||||
|
||||
一键重装脚本 [English](README.en.md)
|
||||
一键 VPS 系统重装脚本 [English](README.en.md)
|
||||
|
||||
[](https://github.com/sponsors/bin456789)
|
||||
## 介绍
|
||||
|
||||
## 亮点
|
||||
|
||||
- 一键安装 Linux,支持 19 种常见发行版
|
||||
- 一键安装 Windows,使用官方 ISO 安装而非自制镜像,脚本会自动获取 ISO 链接、自动安装 Virtio 等常见驱动
|
||||
- 一键重装到 Linux,支持 19 种常见发行版
|
||||
- 一键重装到 Windows,使用官方原版 ISO 而非自制镜像,脚本支持自动查找 ISO 链接、自动安装 `VirtIO` 等公有云驱动
|
||||
- 支持任意方向重装,即 `Linux to Linux`、`Linux to Windows`、`Windows to Windows`、`Windows to Linux`
|
||||
- 无需填写 IP 参数,自动识别动静态,支持 `/32`、`/128`、`网关不在子网范围内`、`纯 IPv6`、`双网卡`
|
||||
- 自动设置 IP,智能设置动静态,支持 `/32`、`/128`、`网关不在子网范围内`、`纯 IPv6`、`IPv4/IPv6 在不同的网卡`
|
||||
- 专门适配低配小鸡,比官方 netboot 需要更少的内存
|
||||
- 全程用分区表 ID 识别硬盘,确保不会写错硬盘
|
||||
- 支持 BIOS、EFI 引导,支持 ARM 服务器
|
||||
- 不含自制包,所有资源均实时从镜像源获得
|
||||
|
||||
如果帮到你,可以请我喝奶茶。
|
||||
[](https://github.com/sponsors/bin456789)
|
||||
|
||||
[](https://github.com/sponsors/bin456789)
|
||||
|
||||
### 反馈
|
||||
|
||||
[](https://github.com/bin456789/reinstall/issues)
|
||||
[](https://t.me/reinstall_os)
|
||||
|
||||
## 快速开始
|
||||
|
||||
- [下载](#下载当前系统是--linux)
|
||||
- [功能 1. 一键重装到 Linux](#功能-1-安装--linux)
|
||||
- [功能 2. 一键 DD Raw 镜像到硬盘](#功能-2-dd-raw-镜像到硬盘)
|
||||
- [功能 3. 一键引导到 Alpine Live OS 内存系统](#功能-3-重启到--alpine-live-os内存系统)
|
||||
- [功能 4. 一键引导到 netboot.xyz](#功能-4-重启到--netbootxyz)
|
||||
- [功能 5. 一键重装到 Windows](#功能-5-安装--windows-iso)
|
||||
|
||||
## 系统要求
|
||||
|
||||
原系统可以是表格中的任意系统
|
||||
@ -31,22 +46,22 @@
|
||||
|
||||
| 系统 | 版本 | 内存 | 硬盘 |
|
||||
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------- | --------- | ------------ |
|
||||
| <img width="16" height="16" src="https://www.alpinelinux.org/alpine-logo.ico" /> Alpine | 3.19, 3.20, 3.21, 3.22 | 256 MB | 1 GB |
|
||||
| <img width="16" height="16" src="https://www.debian.org/favicon.ico" /> Debian | 9, 10, 11, 12 | 256 MB | 1 ~ 1.5 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://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.04 | 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 |
|
||||
| <img width="16" height="16" src="https://img.alicdn.com/imgextra/i1/O1CN01oJnJZg1yK4RzI4Rx2_!!6000000006559-2-tps-118-118.png" /> Anolis | 7, 8, 23 | 512 MB \* | 5 GB |
|
||||
| <img width="16" height="16" src="https://www.redhat.com/favicon.ico" /> RHEL <img width="16" height="16" src="https://almalinux.org/fav/favicon.ico" /> AlmaLinux <img width="16" height="16" src="https://rockylinux.org/favicon.png" /> Rocky <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 <img width="16" height="16" src="https://almalinux.org/fav/favicon.ico" /> AlmaLinux <img width="16" height="16" src="https://rockylinux.org/favicon.png" /> Rocky <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://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://www.openeuler.org/favicon.ico" /> openEuler | 20.03 LTS - 24.03 LTS, 25.03 | 512 MB \* | 5 GB |
|
||||
| <img width="16" height="16" src="https://static.opensuse.org/favicon.ico" /> openSUSE | Leap 15.6, 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://fedoraproject.org/favicon.ico" /> Fedora | 42, 43 | 512 MB \* | 5 GB |
|
||||
| <img width="16" height="16" src="https://www.openeuler.org/favicon.ico" /> openEuler | 20.03 LTS - 24.03 LTS, 25.09 | 512 MB \* | 5 GB |
|
||||
| <img width="16" height="16" src="https://static.opensuse.org/favicon.ico" /> openSUSE | Leap 15.6, 16.0, Tumbleweed (滚动) | 512 MB \* | 5 GB |
|
||||
| <img width="16" height="16" src="https://nixos.org/favicon.svg" /> NixOS | 25.11 | 512 MB | 5 GB |
|
||||
| <img width="16" height="16" src="https://archlinux.org/static/favicon.png" /> Arch | 滚动 | 512 MB | 5 GB |
|
||||
| <img width="16" height="16" src="https://www.gentoo.org/assets/img/logo/gentoo-g.png" /> Gentoo | 滚动 | 512 MB | 5 GB |
|
||||
| <img width="16" height="16" src="https://aosc.io/assets/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://aosc.io/distros/aosc-os.svg" /> 安同 OS | 滚动 | 512 MB | 5 GB |
|
||||
| <img width="16" height="16" src="https://www.fnnas.com/favicon.ico" /> 飞牛 fnOS | 1 | 512 MB | 8 GB |
|
||||
| <img width="16" height="16" src="https://blogs.windows.com/wp-content/uploads/prod/2022/09/cropped-Windows11IconTransparent512-32x32.png" /> Windows (DD) | 任何 | 512 MB | 取决于镜像 |
|
||||
| <img width="16" height="16" src="https://blogs.windows.com/wp-content/uploads/prod/2022/09/cropped-Windows11IconTransparent512-32x32.png" /> Windows (ISO) | Vista, 7, 8.x (Server 2008 - 2012 R2) | 512 MB | 25 GB |
|
||||
| <img width="16" height="16" src="https://blogs.windows.com/wp-content/uploads/prod/2022/09/cropped-Windows11IconTransparent512-32x32.png" /> Windows (ISO) | 10, 11 (Server 2016 - 2025) | 1 GB | 25 GB |
|
||||
@ -56,6 +71,13 @@
|
||||
^ 表示需要 256 MB 内存 + 1.5 GB 硬盘,或 512 MB 内存 + 1 GB 硬盘
|
||||
|
||||
> [!WARNING]
|
||||
>
|
||||
> 本脚本理论上支持独服和 PC
|
||||
>
|
||||
> 但如果能使用 IPMI 或 U 盘,则不建议使用本脚本
|
||||
|
||||
> [!WARNING]
|
||||
>
|
||||
> ❌ 本脚本不支持 OpenVZ、LXC 虚拟机
|
||||
>
|
||||
> 请改用 <https://github.com/LloydAsp/OsMutation>
|
||||
@ -65,13 +87,13 @@
|
||||
国外服务器:
|
||||
|
||||
```bash
|
||||
curl -O https://raw.githubusercontent.com/bin456789/reinstall/main/reinstall.sh || wget -O reinstall.sh $_
|
||||
curl -O https://raw.githubusercontent.com/bin456789/reinstall/main/reinstall.sh || wget -O ${_##*/} $_
|
||||
```
|
||||
|
||||
国内服务器:
|
||||
|
||||
```bash
|
||||
curl -O https://cnb.cool/bin456789/reinstall/-/git/raw/main/reinstall.sh || wget -O reinstall.sh $_
|
||||
curl -O https://cnb.cool/bin456789/reinstall/-/git/raw/main/reinstall.sh || wget -O ${_##*/} $_
|
||||
```
|
||||
|
||||
## 下载(当前系统是 <img width="20" height="20" src="https://blogs.windows.com/wp-content/uploads/prod/2022/09/cropped-Windows11IconTransparent512-32x32.png" /> Windows)
|
||||
@ -113,11 +135,17 @@ certutil -urlcache -f -split https://cnb.cool/bin456789/reinstall/-/git/raw/main
|
||||
|
||||
- Linux 下运行 `bash reinstall.sh ...`
|
||||
- Windows 下先运行 `cmd`,再运行 `reinstall.bat ...`
|
||||
- 如果参数中的链接包含特殊字符,要用 `""` 将链接包起来,不能用 `''`
|
||||
- 如果参数中的链接包含特殊字符,要用 `""` 将链接包裹起来,不能用 `''`
|
||||
|
||||
### 功能 1: 安装 <img width="16" height="16" src="https://www.kernel.org/theme/images/logos/favicon.png" /> Linux
|
||||
|
||||
- 用户名 `root` 默认密码 `123@@@`
|
||||
> [!CAUTION]
|
||||
>
|
||||
> 此功能会清除当前系统**整个硬盘**的全部数据(包含其它分区)!
|
||||
>
|
||||
> 数据无价,请三思而后行!
|
||||
|
||||
- 用户名为 `root`,脚本会提示输入密码,不输入则使用随机密码
|
||||
- 安装最新版可不输入版本号
|
||||
- 最大化利用磁盘空间:不含 boot 分区(Fedora 例外),不含 swap 分区
|
||||
- 自动根据机器类型选择不同的优化内核,例如 `Cloud`、`HWE` 内核
|
||||
@ -127,47 +155,42 @@ certutil -urlcache -f -split https://cnb.cool/bin456789/reinstall/-/git/raw/main
|
||||
```bash
|
||||
bash reinstall.sh anolis 7|8|23
|
||||
rocky 8|9|10
|
||||
oracle 8|9
|
||||
oracle 8|9|10
|
||||
almalinux 8|9|10
|
||||
opencloudos 8|9|23
|
||||
centos 9|10
|
||||
fedora 41|42
|
||||
nixos 25.05
|
||||
debian 9|10|11|12
|
||||
opensuse 15.6|tumbleweed
|
||||
alpine 3.19|3.20|3.21|3.22
|
||||
openeuler 20.03|22.03|24.03|25.03
|
||||
ubuntu 16.04|18.04|20.04|22.04|24.04|25.04 [--minimal]
|
||||
fnos 1
|
||||
nixos 25.11
|
||||
fedora 42|43
|
||||
debian 9|10|11|12|13
|
||||
alpine 3.20|3.21|3.22|3.23
|
||||
opensuse 15.6|16.0|tumbleweed
|
||||
openeuler 20.03|22.03|24.03|25.09
|
||||
ubuntu 16.04|18.04|20.04|22.04|24.04|25.10 [--minimal]
|
||||
kali
|
||||
arch
|
||||
gentoo
|
||||
aosc
|
||||
fnos
|
||||
redhat --img="http://access.cdn.redhat.com/xxx.qcow2"
|
||||
```
|
||||
|
||||
#### 可选参数
|
||||
|
||||
- `--password PASSWORD` 设置密码
|
||||
- `--ssh-key KEY` 设置 SSH 登录公钥,支持以下格式。当使用公钥时,密码为空
|
||||
- `--ssh-key "ssh-rsa ..."`
|
||||
- `--ssh-key "ssh-ed25519 ..."`
|
||||
- `--ssh-key "ecdsa-sha2-nistp256/384/521 ..."`
|
||||
- `--ssh-key http://path/to/public_key`
|
||||
- `--ssh-key github:your_username`
|
||||
- `--ssh-key gitlab:your_username`
|
||||
- `--ssh-key /path/to/public_key`
|
||||
- `--ssh-key C:\path\to\public_key`
|
||||
- `--ssh-key KEY` 设置 SSH 登录公钥,[格式如下](#--ssh-key)。当使用公钥时,密码为空
|
||||
- `--ssh-port PORT` 修改 SSH 端口(安装期间观察日志用,也作用于新系统)
|
||||
- `--web-port PORT` 修改 Web 端口(安装期间观察日志用)
|
||||
- `--frpc-toml /path/to/frpc.toml` 添加 frpc 内网穿透
|
||||
- `--hold 2` 安装结束后不重启,此时可以 SSH 登录修改系统内容,系统挂载在 `/os` (此功能不支持 Debian/Kali)
|
||||
- `--frpc-toml PATH` 添加 frpc 内网穿透,参数填本地路径或 HTTP 链接
|
||||
- `--hold 1` 仅重启到安装环境,不运行安装,用于 SSH 登录验证网络连通性
|
||||
- `--hold 2` 安装结束后不重启,用于 SSH 登录修改系统内容,Debian/Kali 会挂载在 `/target`,其它系统会挂载在 `/os`
|
||||
|
||||
> [!TIP]
|
||||
> 安装 Debian/Kali 时,x86 可通过商家后台 VNC 查看安装进度,ARM 可通过串行控制台查看安装进度。
|
||||
>
|
||||
> 安装其它系统时,可通过多种方式(SSH、HTTP 80 端口、商家后台 VNC、串行控制台)查看安装进度。
|
||||
> <br />即使安装过程出错,也能通过 SSH 运行 `/trans.sh alpine` 安装到 Alpine。
|
||||
> 可通过多种方式(SSH、HTTP 80 端口、商家后台 VNC、串行控制台)查看安装进度。
|
||||
>
|
||||
> 即使安装过程出错,也能连接 SSH 手动救砖。
|
||||
>
|
||||
> 目标系统非 Debian/Kali 时,可以运行 `/trans.sh alpine` 自动救砖成 Alpine 系统。
|
||||
|
||||
<details>
|
||||
|
||||
@ -201,9 +224,15 @@ bash reinstall.sh ubuntu --installer
|
||||
|
||||
</details>
|
||||
|
||||
### 功能 2: DD
|
||||
### 功能 2: DD RAW 镜像到硬盘
|
||||
|
||||
- 支持 `raw` `vhd` 格式的镜像(未压缩,或者压缩成 `.gz` `.xz` `.zst` `.tar` `.tar.gz` `.tar.xz` `.tar.zst`)
|
||||
> [!CAUTION]
|
||||
>
|
||||
> 此功能会清除当前系统**整个硬盘**的全部数据(包含其它分区)!
|
||||
>
|
||||
> 数据无价,请三思而后行!
|
||||
|
||||
- 支持 `raw` 和固定大小的 `vhd` 镜像。未压缩或者压缩成 `.gz` `.xz` `.zst` `.tar` `.tar.gz` `.tar.xz` `.tar.zst`
|
||||
- DD Windows 镜像时,会自动扩展系统盘,静态 IP 的机器会配置好 IP,可能首次开机几分钟后才生效
|
||||
- DD Linux 镜像时,**不会**修改镜像的任何内容
|
||||
|
||||
@ -217,42 +246,49 @@ bash reinstall.sh dd --img "https://example.com/xxx.xz"
|
||||
- `--rdp-port PORT` 修改 RDP 端口 (仅限 DD Windows)
|
||||
- `--ssh-port PORT` 修改 SSH 端口(安装期间观察日志用)
|
||||
- `--web-port PORT` 修改 Web 端口(安装期间观察日志用)
|
||||
- `--frpc-toml /path/to/frpc.toml` 添加 frpc 内网穿透(仅限 DD Windows)
|
||||
- `--hold 2` DD 结束后不重启,此时可以 SSH 登录修改系统内容,Windows 系统会挂载在 `/os`,Linux 系统**不会**自动挂载
|
||||
- `--frpc-toml PATH` 添加 frpc 内网穿透(仅限 DD Windows),参数填本地路径或 HTTP 链接
|
||||
- `--hold 1` 仅重启到安装环境,不运行安装,用于 SSH 登录验证网络连通性
|
||||
- `--hold 2` DD 结束后不重启,用于 SSH 登录修改系统内容,Windows 系统会挂载在 `/os`,Linux 系统**不会**自动挂载
|
||||
|
||||
> [!TIP]
|
||||
>
|
||||
> 可通过多种方式(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(内存系统)
|
||||
|
||||
- 可用 ssh 连接,进行备份/恢复硬盘、手动 DD、修改分区、手动安装 Alpine/Arch/Gentoo 等操作
|
||||
- 用户名 `root` 默认密码 `123@@@`
|
||||
- 如果手动操作没有破坏原系统,再次重启将回到原系统
|
||||
- 可用 ssh 连接,进行备份/恢复硬盘、手动 DD、修改分区、手动安装 Alpine 等操作
|
||||
- 用户名为 `root`,脚本会提示输入密码,不输入则使用随机密码
|
||||
|
||||
> [!TIP]
|
||||
>
|
||||
> 虽然运行的脚本叫 `reinstall`,但是此功能**不会**删除任何数据和进行自动重装,而是要用户手动操作
|
||||
>
|
||||
> 如果用户手动操作没有破坏原系统,再次重启将回到原系统
|
||||
|
||||
```bash
|
||||
bash reinstall.sh alpine --hold=1
|
||||
bash reinstall.sh alpine --hold 1
|
||||
```
|
||||
|
||||
#### 可选参数
|
||||
|
||||
- `--password PASSWORD` 设置密码
|
||||
- `--ssh-port PORT` 修改 SSH 端口
|
||||
- `--ssh-key KEY` 设置 SSH 登录公钥,支持以下格式。当使用公钥时,密码为空
|
||||
- `--ssh-key "ssh-rsa ..."`
|
||||
- `--ssh-key "ssh-ed25519 ..."`
|
||||
- `--ssh-key "ecdsa-sha2-nistp256/384/521 ..."`
|
||||
- `--ssh-key http://path/to/public_key`
|
||||
- `--ssh-key github:your_username`
|
||||
- `--ssh-key gitlab:your_username`
|
||||
- `--ssh-key /path/to/public_key`
|
||||
- `--ssh-key C:\path\to\public_key`
|
||||
- `--frpc-toml /path/to/frpc.toml` 添加 frpc 内网穿透
|
||||
- `--ssh-key KEY` 设置 SSH 登录公钥,[格式如下](#--ssh-key)。当使用公钥时,密码为空
|
||||
- `--frpc-toml PATH` 添加 frpc 内网穿透,参数填本地路径或 HTTP 链接
|
||||
|
||||
### 功能 4: 重启到 <img width="16" height="16" src="https://netboot.xyz/img/favicon.ico" /> netboot.xyz
|
||||
|
||||
- 可使用商家后台 VNC 手动安装 [更多系统](https://github.com/netbootxyz/netboot.xyz?tab=readme-ov-file#what-operating-systems-are-currently-available-on-netbootxyz)
|
||||
- 如果手动操作没有破坏原系统,再次重启将回到原系统
|
||||
|
||||
> [!TIP]
|
||||
>
|
||||
> 虽然运行的脚本叫 `reinstall`,但是此功能**不会**删除任何数据和进行自动重装,而是要用户手动操作
|
||||
>
|
||||
> 如果用户手动操作没有破坏原系统,再次重启将回到原系统
|
||||
|
||||
```bash
|
||||
bash reinstall.sh netboot.xyz
|
||||
@ -264,10 +300,17 @@ bash reinstall.sh netboot.xyz
|
||||
|
||||

|
||||
|
||||
- 用户名 `administrator` 默认密码 `123@@@`
|
||||
> [!CAUTION]
|
||||
>
|
||||
> 此功能会清除当前系统**整个硬盘**的全部数据(包含其它分区)!
|
||||
>
|
||||
> 数据无价,请三思而后行!
|
||||
|
||||
- 用户名为 `administrator`,脚本会提示输入密码,不输入则使用随机密码
|
||||
- 如果远程登录失败,可以尝试使用用户名 `.\administrator`
|
||||
- 静态机器会自动配置好 IP,可能首次开机几分钟后才生效
|
||||
- 支持所有语言
|
||||
- 支持任意语言的 ISO
|
||||
- 支持绕过 Windows 11 硬件限制
|
||||
|
||||
#### 支持的系统
|
||||
|
||||
@ -276,7 +319,7 @@ bash reinstall.sh netboot.xyz
|
||||
- Windows Server Essentials \*
|
||||
- Windows Server (Semi) Annual Channel \*
|
||||
- Hyper-V Server \*
|
||||
- Azure Stack HCI \*
|
||||
- Azure Local (Azure Stack HCI) \*
|
||||
|
||||
#### 方法 1: 让脚本自动查找 ISO
|
||||
|
||||
@ -367,7 +410,6 @@ bash reinstall.sh windows \
|
||||
- <https://www.microsoft.com/software-download/windows11>
|
||||
- <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-iot-enterprise-ltsc-eval>
|
||||
- <https://www.microsoft.com/evalcenter/download-windows-server-2012-r2>
|
||||
@ -386,18 +428,19 @@ bash reinstall.sh windows \
|
||||
- `--password PASSWORD` 设置密码
|
||||
- `--allow-ping` 设置 Windows 防火墙允许被 Ping
|
||||
- `--rdp-port PORT` 更改 RDP 端口
|
||||
- `--ssh-port PORT` 修改 SSH 端口(安装期间观察日志用)
|
||||
- `--web-port PORT` 修改 Web 端口(安装期间观察日志用)
|
||||
- `--ssh-port PORT` 修改 SSH 端口(仅安装期间观察日志用)
|
||||
- `--web-port PORT` 修改 Web 端口(仅安装期间观察日志用)
|
||||
- `--add-driver INF_OR_DIR` 添加额外驱动,填写 .inf 路径,或者 .inf 所在的文件夹
|
||||
- 需先下载驱动到本地
|
||||
- 需先下载驱动到当前系统
|
||||
- 可多次设置该参数以添加不同的驱动
|
||||
- `--frpc-toml /path/to/frpc.toml` 添加 frpc 内网穿透
|
||||
- `--hold 2` 在进入 Windows 官方安装程序之前,可以 SSH 登录修改硬盘内容,硬盘挂载在 `/os`
|
||||
- `--frpc-toml PATH` 添加 frpc 内网穿透,参数填本地路径或 HTTP 链接
|
||||
- `--hold 1` 仅重启到安装环境,不运行安装,用于 SSH 登录验证网络连通性
|
||||
- `--hold 2` 用于在进入 Windows 官方安装程序之前,SSH 登录修改 `boot.wim`、`install.wim` 或者其它内容,硬盘挂载在 `/os`
|
||||
|
||||
#### 以下驱动会自动按需下载安装,无需手动添加
|
||||
|
||||
- Virtio ([Virtio][virtio-virtio], [阿里云][virtio-aliyun], [腾讯云][virtio-qcloud], [GCP][virtio-gcp])
|
||||
- XEN ([~~XEN~~][xen-xen] (未签名), [Citrix][xen-citrix], [AWS][xen-aws])
|
||||
- VirtIO ([社区版][virtio-virtio], [阿里云][virtio-aliyun], [腾讯云][virtio-qcloud], [GCP][virtio-gcp])
|
||||
- XEN ([~~社区版~~][xen-xen] (未签名), [Citrix][xen-citrix], [AWS][xen-aws])
|
||||
- AWS ([ENA 网卡][aws-ena], [NVME 存储控制器][aws-nvme])
|
||||
- GCP ([gVNIC 网卡][gcp-gvnic], [GGA 显卡][gcp-gga])
|
||||
- Azure ([MANA 网卡][azure-mana])
|
||||
@ -421,7 +464,7 @@ bash reinstall.sh windows \
|
||||
[intel-nic-8.1]: https://www.intel.com/content/www/us/en/download/17479/intel-network-adapter-driver-for-windows-8-1.html
|
||||
[intel-nic-10]: https://www.intel.com/content/www/us/en/download/18293/intel-network-adapter-driver-for-windows-10.html
|
||||
[intel-nic-11]: https://www.intel.com/content/www/us/en/download/727998/intel-network-adapter-driver-for-microsoft-windows-11.html
|
||||
[intel-nic-2008-r2]: https://www.intel.com/content/www/us/en/download/15591/intel-network-adapter-driver-for-windows-server-2008-r2-final-release.html
|
||||
[intel-nic-2008-r2]: https://web.archive.org/web/20250501002542/https://www.intel.com/content/www/us/en/download/15591/intel-network-adapter-driver-for-windows-server-2008-r2-final-release.html
|
||||
[intel-nic-2012]: https://www.intel.com/content/www/us/en/download/16789/intel-network-adapter-driver-for-windows-server-2012.html
|
||||
[intel-nic-2012-r2]: https://www.intel.com/content/www/us/en/download/17480/intel-network-adapter-driver-for-windows-server-2012-r2.html
|
||||
[intel-nic-2016]: https://www.intel.com/content/www/us/en/download/18737/intel-network-adapter-driver-for-windows-server-2016.html
|
||||
@ -431,7 +474,7 @@ bash reinstall.sh windows \
|
||||
|
||||
#### 如何填写映像名称 `--image-name`
|
||||
|
||||
通常一个 ISO 会包含多个系统版本,例如家庭版、专业版。映像名称 `--image-name` 就是用来指定要安装的版本,填写时不区分大小写
|
||||
一个 ISO 通常包含多个系统版本,例如家庭版、专业版。因此需要用 `--image-name` 指定要安装的系统版本(映像名称),不区分大小写
|
||||
|
||||
可以用 DISM、DISM++、Wimlib 等工具查询 ISO 包含的映像名称
|
||||
|
||||
@ -454,15 +497,29 @@ Windows Server 2025 SERVERDATACENTER
|
||||
> Vista (Server 2008) 和 32 位系统可能会缺少驱动
|
||||
|
||||
> [!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]
|
||||
>
|
||||
> 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>
|
||||
|
||||
> [!WARNING]
|
||||
>
|
||||
> 在 GCP 上安装 `2022年5月` 和之后发布的 Windows ISO,在引导 Windows 安装界面 (PE) 时会不断反复重启。解决方法如下,二选一
|
||||
>
|
||||
> 1. 添加 `--force-boot-mode bios` 参数,脚本将以 `BIOS 引导 + MBR 分区表` 方式安装 Windows
|
||||
>
|
||||
> (可选) 安装完成后用 `MBR2GPT /convert /allowFullOS` 命令转为 `EFI 引导 + GPT 分区表`
|
||||
>
|
||||
> 2. 自制 RAW 镜像并通过 DD 安装
|
||||
|
||||
#### ARM 安装 Windows 的注意事项
|
||||
|
||||
大部分 ARM 机器都支持安装最新版 Windows 11
|
||||
@ -492,10 +549,33 @@ Windows Server 2025 SERVERDATACENTER
|
||||
|
||||
</details>
|
||||
|
||||
## 讨论
|
||||
## 参数格式
|
||||
|
||||
[](https://github.com/bin456789/reinstall/issues)
|
||||
[](https://t.me/reinstall_os)
|
||||
### --ssh-key
|
||||
|
||||
- `--ssh-key "ssh-rsa ..."`
|
||||
- `--ssh-key "ssh-ed25519 ..."`
|
||||
- `--ssh-key "ecdsa-sha2-nistp256/384/521 ..."`
|
||||
- `--ssh-key http://path/to/public_key`
|
||||
- `--ssh-key github:your_username`
|
||||
- `--ssh-key gitlab:your_username`
|
||||
- `--ssh-key /path/to/public_key`
|
||||
- `--ssh-key C:\path\to\public_key`
|
||||
|
||||
## 如何使用旧版本
|
||||
|
||||
根据 Bug 守恒定律,修复旧 Bug 的同时会引入新的 Bug
|
||||
|
||||
如果遇到新的 Bug,可以试下旧版本是否正常
|
||||
|
||||
从 <https://github.com/bin456789/reinstall/commits/main> 右侧找到旧版本的 `commit_id`
|
||||
|
||||
```bash
|
||||
commit_id=xxxxxxx
|
||||
curl -O https://raw.githubusercontent.com/bin456789/reinstall/$commit_id/reinstall.sh || wget -O ${_##*/} $_
|
||||
sed -i "/^confhome.*main$/s/main/$commit_id/" reinstall.sh
|
||||
bash reinstall.sh ...
|
||||
```
|
||||
|
||||
## 如何修改脚本自用
|
||||
|
||||
@ -505,8 +585,6 @@ Windows Server 2025 SERVERDATACENTER
|
||||
|
||||
## 感谢
|
||||
|
||||
[](https://github.com/sponsors/bin456789)
|
||||
|
||||
感谢以下商家提供白嫖机器
|
||||
|
||||
[](https://www.oracle.com/cloud/)
|
||||
|
||||
155
debian.cfg
155
debian.cfg
@ -2,14 +2,14 @@
|
||||
# shellcheck disable=SC1091,SC2148
|
||||
# https://www.debian.org/releases/stable/amd64/apbs04.zh-cn.html
|
||||
# https://www.debian.org/releases/stable/example-preseed.txt
|
||||
# https://preseed.debian.net/debian-preseed/bookworm/amd64-main-full.txt
|
||||
# https://preseed.debian.net/debian-preseed/trixie/amd64-main-full.txt
|
||||
# 需要留意 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. 本地化
|
||||
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
|
||||
|
||||
# B.4.2. 网络设置
|
||||
@ -25,10 +25,10 @@ d-i mirror/country string manual
|
||||
|
||||
# B.4.5. 帐号设置
|
||||
d-i passwd/make-user boolean false
|
||||
# 单纯为了跳过设置,实际上是在 partman/early_command 里设置密码,preseed/early_command 无法设置密码
|
||||
# 注意如果用 ssh key 后面还要删除密码
|
||||
d-i passwd/root-password password ''
|
||||
d-i passwd/root-password-again password ''
|
||||
# d-i passwd/root-password password ''
|
||||
# d-i passwd/root-password-again password ''
|
||||
# d-i passwd/root-password-crypted password ''
|
||||
# kali 需要下面这行,否则会提示输入用户名
|
||||
d-i passwd/root-login boolean true
|
||||
|
||||
@ -63,6 +63,9 @@ d-i partman-efi/non_efi_system boolean true
|
||||
# 选择 true 就一直死循环
|
||||
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-amd64-efi/atomic?ref_type=heads
|
||||
@ -73,6 +76,7 @@ d-i partman-auto/expert_recipe_efi string efi :: \
|
||||
1 1 -1 $default_filesystem \
|
||||
method{ format } format{ } use_filesystem{ } $default_filesystem{ } mountpoint{ / } .
|
||||
|
||||
# 大于 2T 会自动用 gpt
|
||||
# shellcheck disable=SC1083,SC2086,SC2154
|
||||
d-i partman-auto/expert_recipe_bios string bios :: \
|
||||
1 1 1 free \
|
||||
@ -99,26 +103,127 @@ d-i pkgsel/upgrade select none
|
||||
d-i grub-installer/force-efi-extra-removable boolean true
|
||||
|
||||
# B.4.12. 完成安装
|
||||
d-i finish-install/reboot_in_progress note
|
||||
# 由下面的 hold 2 设置
|
||||
# d-i finish-install/reboot_in_progress note
|
||||
|
||||
# B.4.13. 预置其他的软件包
|
||||
|
||||
# 其他设置
|
||||
# d-i anna/standard_modules boolean false
|
||||
# d-i anna/choose_modules string network-console
|
||||
# d-i network-console/password password 123@@@
|
||||
# d-i network-console/password-again password 123@@@
|
||||
# d-i network-console/password password ''
|
||||
# d-i network-console/password-again password ''
|
||||
|
||||
# B.5.1. 安装过程中运行用户命令
|
||||
# 注意所有命令都会合并成一行命令
|
||||
|
||||
# 最后的 true; \ 没什么用,只是让 vscode 代码高亮不报错误
|
||||
|
||||
# debian 11+ 才有 websocketd
|
||||
|
||||
# 有 /cdrom/simple-cdd 才安装 simple-cdd-profiles
|
||||
# 不然安装时 control 脚本会报错:
|
||||
# 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; \
|
||||
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 12 initrd 没有 xargs
|
||||
@ -132,10 +237,11 @@ d-i partman/early_command string true; \
|
||||
true >$postinst; \
|
||||
|
||||
swapfile=/target/swapfile; \
|
||||
mem=$(grep ^MemTotal: /proc/meminfo | { read -r _ y _; echo "$y"; }); \
|
||||
mem=$((mem / 1024)); \
|
||||
mem=$(grep ^MemTotal: /proc/meminfo | { read -r _ y _; echo "$((y / 1024))"; }); \
|
||||
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; \
|
||||
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); \
|
||||
|
||||
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)"; \
|
||||
[ -d /sys/firmware/efi ] || debconf-set partman-auto/expert_recipe "$(debconf-get partman-auto/expert_recipe_bios)"; \
|
||||
|
||||
debconf-set passwd/root-password-crypted "$(cat /configs/password-linux-sha512)"; \
|
||||
if [ -d /sys/firmware/efi ]; then \
|
||||
debconf-set partman-auto/expert_recipe "$(debconf-get partman-auto/expert_recipe_efi)"; \
|
||||
else \
|
||||
debconf-set partman-auto/expert_recipe "$(debconf-get partman-auto/expert_recipe_bios)"; \
|
||||
fi; \
|
||||
|
||||
true >/bin/os-prober
|
||||
|
||||
@ -188,17 +297,11 @@ d-i preseed/late_command string true; \
|
||||
fi; \
|
||||
|
||||
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/etc/frpc; \
|
||||
for i in {1..5}; do \
|
||||
wget -O /target/frpc.tar.gz "$url" && break; \
|
||||
done; \
|
||||
tar xzf /target/frpc.tar.gz "$basename/frpc" -O >/target/usr/local/bin/frpc; \
|
||||
rm -f /target/frpc.tar.gzx; \
|
||||
cp /usr/local/bin/frpc /target/usr/local/bin/; \
|
||||
cp /usr/local/etc/frpc/frpc.toml /target/usr/local/etc/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/; \
|
||||
in-target systemctl enable frpc; \
|
||||
fi; \
|
||||
|
||||
@ -48,21 +48,40 @@ retry() {
|
||||
# 用 systemd-analyze plot >a.svg 发现 sys-subsystem-net-devices-enp3s0.device 也是出现在 NetworkManager 之后
|
||||
# 因此需要等待网卡出现
|
||||
get_ethx_by_mac() {
|
||||
mac=$(echo "$1" | to_lower)
|
||||
retry 10 _get_ethx_by_mac "$mac"
|
||||
retry 10 _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 [ "$flag" = master ]; then
|
||||
# master
|
||||
# 过滤 azure vf (带 master ethx)
|
||||
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
|
||||
for i in $(cd /sys/class/net && echo *); do
|
||||
if [ "$(cat "/sys/class/net/$i/address")" = "$mac" ]; then
|
||||
if [ $(($(cat "/sys/class/net/$i/flags") & 0x800)) -ne 0 ]; then
|
||||
fact_flag=slave
|
||||
else
|
||||
fact_flag=master
|
||||
fi
|
||||
if [ "$flag" = "$fact_flag" ]; then
|
||||
echo "$i"
|
||||
return
|
||||
fi
|
||||
fi
|
||||
done
|
||||
return 1
|
||||
fi
|
||||
@ -138,6 +157,23 @@ fix_network_manager() {
|
||||
|
||||
# 更改文件名
|
||||
mv "$file" "$proper_file"
|
||||
|
||||
# NM 不会自动忽略 Azure 的 slave 网卡,需手动设置
|
||||
# azure 文档中的方法不够通用,只适合 azure
|
||||
# https://learn.microsoft.com/zh-cn/azure/virtual-network/accelerated-networking-overview
|
||||
|
||||
# 我们采用红帽的方法
|
||||
# https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/8/html/configuring_and_managing_networking/configuring-networkmanager-to-ignore-certain-devices_configuring-and-managing-networking
|
||||
if slave_ethx=$(get_ethx_by_mac "$mac" slave); then
|
||||
cat >"/etc/NetworkManager/conf.d/99-$slave_ethx-unmanaged.conf" <<EOF
|
||||
[device-$slave_ethx-unmanaged]
|
||||
match-device=interface-name:$slave_ethx
|
||||
managed=0
|
||||
EOF
|
||||
fi
|
||||
|
||||
# 也可以设置 unmanaged-devices, 但是官方文档不推荐
|
||||
# https://networkmanager.pages.freedesktop.org/NetworkManager/NetworkManager/NetworkManager.conf.html#:~:text=may%20be%20a-,better%20choice,-.
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
serverAddr = "YOUR_FRP_SERVER_IP"
|
||||
serverAddr = "11.22.33.44"
|
||||
serverPort = 7000
|
||||
auth.token = "YOUR_FRP_TOKEN"
|
||||
auth.token = "123456"
|
||||
|
||||
[[proxies]]
|
||||
name = "ssh"
|
||||
|
||||
@ -10,7 +10,7 @@ is_in_china() {
|
||||
}
|
||||
|
||||
is_ipv6_only() {
|
||||
! grep -q 1 /dev/netconf/eth*/ipv4_has_internet
|
||||
! grep -q 1 /dev/netconf/*/ipv4_has_internet
|
||||
}
|
||||
|
||||
get_frpc_url() {
|
||||
|
||||
@ -240,11 +240,17 @@ test_connect() {
|
||||
test_internet() {
|
||||
for i in $(seq 5); do
|
||||
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."
|
||||
ipv4_has_internet=true
|
||||
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."
|
||||
ipv6_has_internet=true
|
||||
fi
|
||||
@ -339,8 +345,9 @@ EOF
|
||||
db_progress INFO netcfg/link_detect_progress
|
||||
else
|
||||
# alpine
|
||||
# h3c 移动云电脑使用 udhcpc 会重复提示 sending select,无法获得 ipv6,因此使用 dhcpcd
|
||||
method=dhcpcd
|
||||
# h3c 移动云电脑使用 udhcpc 会重复提示 sending select,无法获得 ipv6
|
||||
# dhcpcd 会配置租约时间,过期会移除 IP,但我们的没有在后台运行 dhcpcd ,因此用 udhcpc
|
||||
method=udhcpc
|
||||
|
||||
case "$method" in
|
||||
udhcpc)
|
||||
@ -369,6 +376,10 @@ else
|
||||
sleep $DNS_FILE_TIMEOUT # 需要等待写入 dns
|
||||
dhcpcd -x "$ethx" # 终止
|
||||
fi
|
||||
# autoconf 和 accept_ra 会被 dhcpcd 自动关闭,因此需要重新打开
|
||||
# 如果没重新打开,重新运行 dhcpcd 命令依然可以正常生成 slaac 地址和路由
|
||||
sysctl -w "net.ipv6.conf.$ethx.autoconf=1"
|
||||
sysctl -w "net.ipv6.conf.$ethx.accept_ra=1"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
@ -66,6 +66,12 @@
|
||||
const scrollToBottomButton = document.getElementById('scroll-to-bottom');
|
||||
let shouldScrollToBottom = true;
|
||||
|
||||
// 缓冲区相关
|
||||
let messageBuffer = [];
|
||||
let flushScheduled = false;
|
||||
const BUFFER_FLUSH_INTERVAL = 100; // 毫秒
|
||||
const BUFFER_MAX_SIZE = 50; // 最大缓冲消息数
|
||||
|
||||
scrollToBottomButton.addEventListener('click', () => {
|
||||
logContainer.scrollTop = logContainer.scrollHeight;
|
||||
});
|
||||
@ -81,30 +87,71 @@
|
||||
shouldScrollToBottom = isAtBottom;
|
||||
});
|
||||
|
||||
var ws = new ReconnectingWebSocket('ws://' + location.host + '/');
|
||||
ws.onopen = function () {
|
||||
logContainer.textContent += '\nWebSocket Connected.';
|
||||
};
|
||||
ws.onclose = function () {
|
||||
logContainer.textContent += '\nWebSocket Disconnected.';
|
||||
};
|
||||
ws.onmessage = function (event) {
|
||||
logContainer.textContent += '\n' + event.data;
|
||||
// 刷新缓冲区到 DOM
|
||||
function flushBuffer() {
|
||||
if (messageBuffer.length === 0) {
|
||||
flushScheduled = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// 批量更新文本内容
|
||||
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) {
|
||||
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>
|
||||
</body>
|
||||
|
||||
453
reinstall.sh
453
reinstall.sh
@ -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://www.ghproxy.cc/https://raw.githubusercontent.com/bin456789/reinstall/main
|
||||
|
||||
# 默认密码
|
||||
DEFAULT_PASSWORD=123@@@
|
||||
|
||||
# 用于判断 reinstall.sh 和 trans.sh 是否兼容
|
||||
SCRIPT_VERSION=4BACD833-A585-23BA-6CBB-9AA4E08E0003
|
||||
SCRIPT_VERSION=4BACD833-A585-23BA-6CBB-9AA4E08E0004
|
||||
|
||||
# 记录要用到的 windows 程序,运行时输出删除 \r
|
||||
WINDOWS_EXES='cmd powershell wmic reg diskpart netsh bcdedit mountvol'
|
||||
@ -25,6 +22,22 @@ export LC_ALL=C
|
||||
# 不要漏了最后的 $PATH,否则会找不到 windows 系统程序例如 diskpart
|
||||
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$PATH
|
||||
|
||||
# 如果不是 bash 的话,继续执行会有语法错误,因此在这里判断是否 bash
|
||||
if [ -z "$BASH" ]; then
|
||||
if [ -f /etc/alpine-release ]; then
|
||||
if ! apk add bash; then
|
||||
echo "Error while install bash." >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
if command -v bash >/dev/null; then
|
||||
exec bash "$0" "$@"
|
||||
else
|
||||
echo "Please run this script with bash." >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# 记录日志,过滤含有 password 的行
|
||||
exec > >(tee >(grep -iv password >>/reinstall.log)) 2>&1
|
||||
THIS_SCRIPT=$(readlink -f "$0")
|
||||
@ -48,21 +61,21 @@ usage_and_exit() {
|
||||
Usage: $reinstall_____ anolis 7|8|23
|
||||
opencloudos 8|9|23
|
||||
rocky 8|9|10
|
||||
oracle 8|9
|
||||
oracle 8|9|10
|
||||
almalinux 8|9|10
|
||||
centos 9|10
|
||||
fedora 41|42
|
||||
nixos 25.05
|
||||
debian 9|10|11|12
|
||||
opensuse 15.6|tumbleweed
|
||||
alpine 3.19|3.20|3.21|3.22
|
||||
openeuler 20.03|22.03|24.03|25.03
|
||||
ubuntu 16.04|18.04|20.04|22.04|24.04|25.04 [--minimal]
|
||||
fnos 1
|
||||
nixos 25.11
|
||||
fedora 42|43
|
||||
debian 9|10|11|12|13
|
||||
alpine 3.20|3.21|3.22|3.23
|
||||
opensuse 15.6|16.0|tumbleweed
|
||||
openeuler 20.03|22.03|24.03|25.09
|
||||
ubuntu 16.04|18.04|20.04|22.04|24.04|25.10 [--minimal]
|
||||
kali
|
||||
arch
|
||||
gentoo
|
||||
aosc
|
||||
fnos
|
||||
redhat --img="http://access.cdn.redhat.com/xxx.qcow2"
|
||||
dd --img="http://xxx.com/yyy.zzz" (raw image stores in raw/vhd/tar/gz/xz/zst)
|
||||
windows --image-name="windows xxx yyy" --lang=xx-yy
|
||||
@ -74,7 +87,7 @@ Usage: $reinstall_____ anolis 7|8|23
|
||||
[--ssh-key KEY]
|
||||
[--ssh-port PORT]
|
||||
[--web-port PORT]
|
||||
[--frpc-toml TOML]
|
||||
[--frpc-toml PATH]
|
||||
|
||||
For Windows Only:
|
||||
[--allow-ping]
|
||||
@ -126,14 +139,35 @@ error_and_exit() {
|
||||
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() {
|
||||
is_have_cmd curl || install_pkg curl
|
||||
|
||||
# 显示 url
|
||||
show_url_in_args "$@" >&2
|
||||
|
||||
# 添加 -f, --fail,不然 404 退出码也为0
|
||||
# 32位 cygwin 已停止更新,证书可能有问题,先添加 --insecure
|
||||
# centos 7 curl 不支持 --retry-connrefused --retry-all-errors
|
||||
# 因此手动 retry
|
||||
grep -o 'http[^ ]*' <<<"$@" >&2
|
||||
for i in $(seq 5); do
|
||||
if command curl --insecure --connect-timeout 10 -f "$@"; then
|
||||
return
|
||||
@ -280,11 +314,21 @@ get_function_content() {
|
||||
}
|
||||
|
||||
insert_into_file() {
|
||||
file=$1
|
||||
location=$2
|
||||
regex_to_find=$3
|
||||
local file=$1
|
||||
local location=$2
|
||||
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)
|
||||
if [ ! "$found_count" -eq 1 ]; then
|
||||
@ -813,30 +857,22 @@ is_have_arm_version() {
|
||||
case "$version" in
|
||||
10)
|
||||
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 ;;
|
||||
# arm ltsc 只有 2021 有 iso
|
||||
'enterprise ltsc 2021' | 'iot enterprise ltsc 2021') return ;;
|
||||
esac
|
||||
;;
|
||||
11)
|
||||
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
|
||||
;;
|
||||
11) return ;;
|
||||
esac
|
||||
return 1
|
||||
}
|
||||
|
||||
find_windows_iso() {
|
||||
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."
|
||||
fi
|
||||
if [ "$basearch" = 'aarch64' ] && ! is_have_arm_version; then
|
||||
error_and_exit "No ARM iso for this Windows Version."
|
||||
fi
|
||||
|
||||
if [ -z "$lang" ]; then
|
||||
lang=en-us
|
||||
@ -865,6 +901,7 @@ get_windows_iso_link() {
|
||||
serverdatacenter | serverdatacentercore) echo _ ;;
|
||||
esac
|
||||
;;
|
||||
# massgrave 不提供 2012 下载
|
||||
'2012 r2' | \
|
||||
2016 | 2019 | 2022 | 2025)
|
||||
case "$edition" in
|
||||
@ -882,24 +919,42 @@ get_windows_iso_link() {
|
||||
x86) echo _ ;;
|
||||
esac
|
||||
;;
|
||||
homebasic | homepremium | business | ultimate) echo _ ;;
|
||||
homebasic | homepremium | ultimate) echo _ ;;
|
||||
business | enterprise) echo "$edition" ;;
|
||||
esac
|
||||
;;
|
||||
7)
|
||||
case "$edition" in
|
||||
starter)
|
||||
case "$arch_win" in
|
||||
x86) echo ultimate ;;
|
||||
x86) echo starter ;;
|
||||
esac
|
||||
;;
|
||||
homebasic | homepremium | professional | ultimate) echo ultimate ;;
|
||||
homebasic)
|
||||
case "$arch_win" in
|
||||
x86) echo "home basic" ;;
|
||||
esac
|
||||
;;
|
||||
homepremium) echo "home premium" ;;
|
||||
professional | enterprise | ultimate) echo "$edition" ;;
|
||||
esac
|
||||
;;
|
||||
8 | 8.1)
|
||||
case "$edition" in
|
||||
'') echo _ ;; # windows 8.x core
|
||||
pro | enterprise) echo "$edition" ;;
|
||||
esac
|
||||
;;
|
||||
# 8.1 需到 msdl.gravesoft.dev 下载
|
||||
10)
|
||||
case "$edition" in
|
||||
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 enterprise') echo 'iot enterprise' ;;
|
||||
# iot ltsc
|
||||
@ -916,13 +971,23 @@ get_windows_iso_link() {
|
||||
esac
|
||||
;;
|
||||
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
|
||||
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 enterprise' | 'iot enterprise subscription') echo 'iot enterprise' ;;
|
||||
# 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
|
||||
'enterprise ltsc 2024')
|
||||
# arm64 的 enterprise ltsc 2024 要下载 iot enterprise ltsc 2024 iso
|
||||
@ -947,6 +1012,11 @@ get_windows_iso_link() {
|
||||
esac
|
||||
}
|
||||
|
||||
# msdl 没有每月发布的 iso
|
||||
# msdl 只有 consumer 版本,因此里面的 pro 版本不是 vl 版
|
||||
# 8.1 没有每月发布的 iso,因此优先从 msdl 下载
|
||||
# win10 22h2 arm 有每月发布的 iso,因此不从 msdl 下载
|
||||
# win10/11 ltsc 没有每月发布的 iso,但是 msdl 没有 ltsc 版本
|
||||
get_label_msdl() {
|
||||
case "$version" in
|
||||
8.1)
|
||||
@ -954,15 +1024,6 @@ get_windows_iso_link() {
|
||||
'' | pro) echo _ ;;
|
||||
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
|
||||
}
|
||||
|
||||
@ -975,7 +1036,7 @@ get_windows_iso_link() {
|
||||
echo server
|
||||
else
|
||||
case "$version" in
|
||||
vista | 7 | 8.1 | 10 | 11)
|
||||
vista | 7 | 8 | 8.1 | 10 | 11)
|
||||
echo "$version"
|
||||
;;
|
||||
esac
|
||||
@ -992,7 +1053,13 @@ get_windows_iso_link() {
|
||||
label_vlsc=$(get_label_vlsc)
|
||||
page=$(get_page)
|
||||
|
||||
if [ "$page" = vista ]; then
|
||||
page_url=https://massgrave.dev/windows_vista__links
|
||||
elif [ "$page" = server ]; then
|
||||
page_url=https://massgrave.dev/windows-server-links
|
||||
else
|
||||
page_url=https://massgrave.dev/windows_${page}_links
|
||||
fi
|
||||
|
||||
info "Find windows iso"
|
||||
echo "Version: $version"
|
||||
@ -1003,14 +1070,23 @@ get_windows_iso_link() {
|
||||
echo "List: $page_url"
|
||||
echo
|
||||
|
||||
# 先判断是否能自动查找该版本
|
||||
# 再判断是否支持 arm
|
||||
# 这样可以在输入错误 Edition 时例如 windows 11 enterprise ltsc 2021
|
||||
# 显示名称错误,而不是显示该版本不支持 arm
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
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 的
|
||||
# 例如查找 windows 10 iot enterprise,会得到
|
||||
@ -1109,6 +1185,10 @@ setos() {
|
||||
[ "$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 源
|
||||
# shellcheck disable=SC2034
|
||||
is_debian_elts && elts=1 || elts=0
|
||||
@ -1118,6 +1198,9 @@ setos() {
|
||||
10) codename=buster ;;
|
||||
11) codename=bullseye ;;
|
||||
12) codename=bookworm ;;
|
||||
13) codename=trixie ;;
|
||||
14) codename=forky ;;
|
||||
15) codename=duke ;;
|
||||
esac
|
||||
|
||||
if ! is_use_cloud_image && is_debian_elts && is_in_china; then
|
||||
@ -1224,6 +1307,7 @@ Continue?
|
||||
eval ${step}_vmlinuz=$mirror/linux
|
||||
eval ${step}_initrd=$mirror/initrd.gz
|
||||
eval ${step}_ks=$confhome/debian.cfg
|
||||
eval ${step}_deb_mirror=$hostname/kali
|
||||
eval ${step}_udeb_mirror=$hostname/kali
|
||||
eval ${step}_codename=$codename
|
||||
eval ${step}_kernel=linux-image$flavour-$basearch_alt
|
||||
@ -1238,7 +1322,7 @@ Continue?
|
||||
20.04) codename=focal ;;
|
||||
22.04) codename=jammy ;;
|
||||
24.04) codename=noble ;;
|
||||
25.04) codename=plucky ;; # non-lts
|
||||
25.10) codename=questing ;; # non-lts
|
||||
esac
|
||||
|
||||
if is_use_cloud_image; then
|
||||
@ -1412,26 +1496,17 @@ Continue?
|
||||
else
|
||||
# leap
|
||||
dir=distribution/leap/$releasever/appliances
|
||||
if [ "$releasever" = 15.6 ]; then
|
||||
file=openSUSE-Leap-$releasever-Minimal-VM.$basearch-Cloud.qcow2
|
||||
case "$releasever" in
|
||||
15.6) file=openSUSE-Leap-$releasever-Minimal-VM.$basearch-Cloud.qcow2 ;;
|
||||
16.0) file=Leap-$releasever-Minimal-VM.$basearch-Cloud.qcow2 ;;
|
||||
# 16.0) file=Leap-$releasever-Minimal-VM.$basearch-kvm$(if [ "$basearch" = x86_64 ]; then echo '-and-xen'; fi).qcow2 ;;
|
||||
esac
|
||||
|
||||
# https://src.opensuse.org/openSUSE/Leap-Images/src/branch/leap-16.0/kiwi-templates-Minimal/Minimal.kiwi
|
||||
# https://build.opensuse.org/projects/Virtualization:Appliances:Images:openSUSE-Leap-15.6/packages/kiwi-templates-Minimal/files/Minimal.kiwi
|
||||
# https://build.opensuse.org/projects/Virtualization:Appliances:Images:openSUSE-Tumbleweed/packages/kiwi-templates-Minimal/files/Minimal.kiwi
|
||||
# 有专门的kvm镜像,openSUSE-Leap-15.5-Minimal-VM.x86_64-kvm-and-xen.qcow2,里面没有cloud-init
|
||||
# file=openSUSE-Leap-15.5-Minimal-VM.x86_64-kvm-and-xen.qcow2
|
||||
else
|
||||
# https://src.opensuse.org/openSUSE/Leap/raw/branch/16.0/Leap/Leap.kiwi
|
||||
# Default 比 Base 多了以下组件
|
||||
# <namedCollection name="salt_minion" />
|
||||
# <package name="patterns-base-salt_minion" />
|
||||
# <namedCollection name="kvm_host" />
|
||||
# <package name="patterns-base-kvm_host" />
|
||||
# <package name="lzop" />
|
||||
# <package name="wpa_supplicant" arch="x86_64,aarch64" />
|
||||
# <package name="k3s-install" />
|
||||
|
||||
# file=Leap.x86_64-Default.raw.xz
|
||||
file=Leap.x86_64-Base.raw.xz
|
||||
fi
|
||||
fi
|
||||
eval ${step}_img=$mirror/$dir/$file
|
||||
}
|
||||
@ -1605,7 +1680,9 @@ Continue with DD?
|
||||
fi
|
||||
|
||||
elarch=$basearch
|
||||
if [ "$distro" = almalinux ] && [ "$basearch" = x86_64 ] && ! is_cpu_supports_x86_64_v3; then
|
||||
if [ "$basearch" = x86_64 ] &&
|
||||
[ "$distro" = almalinux ] && [ "$releasever" -ge 10 ] &&
|
||||
! is_cpu_supports_x86_64_v3; then
|
||||
elarch=x86_64_v2
|
||||
fi
|
||||
|
||||
@ -1738,7 +1815,12 @@ Continue with DD?
|
||||
|
||||
if is_use_cloud_image; then
|
||||
# ci
|
||||
if [ "$releasever" -eq 9 ]; then
|
||||
dir=$releasever/images/qcow2/$basearch
|
||||
else
|
||||
dir=$releasever/images/$basearch
|
||||
fi
|
||||
|
||||
file=$(curl -L $mirror/$dir/ | grep -oP 'OpenCloudOS.*?\.qcow2' |
|
||||
sort -uV | tail -1 | grep .)
|
||||
eval ${step}_img=$mirror/$dir/$file
|
||||
@ -1835,20 +1917,20 @@ verify_os_name() {
|
||||
'opencloudos 8|9|23' \
|
||||
'almalinux 8|9|10' \
|
||||
'rocky 8|9|10' \
|
||||
'oracle 8|9' \
|
||||
'fedora 41|42' \
|
||||
'nixos 25.05' \
|
||||
'debian 9|10|11|12' \
|
||||
'oracle 8|9|10' \
|
||||
'fnos 1' \
|
||||
'fedora 42|43' \
|
||||
'nixos 25.11' \
|
||||
'debian 9|10|11|12|13' \
|
||||
'opensuse 15.6|16.0|tumbleweed' \
|
||||
'alpine 3.19|3.20|3.21|3.22' \
|
||||
'openeuler 20.03|22.03|24.03|25.03' \
|
||||
'ubuntu 16.04|18.04|20.04|22.04|24.04|25.04' \
|
||||
'alpine 3.20|3.21|3.22|3.23' \
|
||||
'openeuler 20.03|22.03|24.03|25.09' \
|
||||
'ubuntu 16.04|18.04|20.04|22.04|24.04|25.10' \
|
||||
'redhat' \
|
||||
'kali' \
|
||||
'arch' \
|
||||
'gentoo' \
|
||||
'aosc' \
|
||||
'fnos' \
|
||||
'windows' \
|
||||
'dd' \
|
||||
'netboot.xyz'; do
|
||||
@ -1902,8 +1984,7 @@ install_pkg() {
|
||||
# 因为可能装了多种包管理器
|
||||
if [ -f /etc/os-release ]; then
|
||||
# shellcheck source=/dev/null
|
||||
. /etc/os-release
|
||||
for id in $ID $ID_LIKE; do
|
||||
for id in $({ . /etc/os-release && echo $ID $ID_LIKE; }); do
|
||||
# https://github.com/chef/os_release
|
||||
case "$id" in
|
||||
fedora | centos | rhel) is_have_cmd dnf && pkg_mgr=dnf || pkg_mgr=yum ;;
|
||||
@ -2104,6 +2185,10 @@ install_pkg() {
|
||||
done >&2
|
||||
}
|
||||
|
||||
is_valid_ram_size() {
|
||||
is_digit "$1" && [ "$1" -gt 0 ]
|
||||
}
|
||||
|
||||
check_ram() {
|
||||
ram_standard=$(
|
||||
case "$distro" in
|
||||
@ -2131,7 +2216,7 @@ check_ram() {
|
||||
)
|
||||
|
||||
if is_in_windows; then
|
||||
ram_size=$(wmic memorychip get capacity | awk -F= '{sum+=$2} END {print sum/1024/1024}')
|
||||
ram_size=$(wmic memorychip get capacity | awk -F= '{sum+=$2} END {if(sum>0) print sum/1024/1024}')
|
||||
else
|
||||
# lsmem最准确但 centos7 arm 和 alpine 不能用,debian 9 util-linux 没有 lsmem
|
||||
# arm 24g dmidecode 显示少了128m
|
||||
@ -2140,12 +2225,12 @@ check_ram() {
|
||||
install_pkg lsmem
|
||||
ram_size=$(lsmem -b 2>/dev/null | grep 'Total online memory:' | awk '{ print $NF/1024/1024 }')
|
||||
|
||||
if [ -z $ram_size ]; then
|
||||
if ! is_valid_ram_size "$ram_size"; then
|
||||
install_pkg dmidecode
|
||||
ram_size=$(dmidecode -t 17 | grep "Size.*[GM]B" | awk '{if ($3=="GB") s+=$2*1024; else s+=$2} END {print s}')
|
||||
ram_size=$(dmidecode -t 17 | grep "Size.*[GM]B" | awk '{if ($3=="GB") s+=$2*1024; else s+=$2} END {if(s>0) print s}')
|
||||
fi
|
||||
|
||||
if [ -z $ram_size ]; then
|
||||
if ! is_valid_ram_size "$ram_size"; then
|
||||
install_pkg lshw
|
||||
# 不能忽略 -i,alpine 显示的是 System memory
|
||||
ram_str=$(lshw -c memory -short | grep -i 'System Memory' | awk '{print $3}')
|
||||
@ -2156,12 +2241,12 @@ check_ram() {
|
||||
|
||||
# 用于兜底,不太准确
|
||||
# cygwin 要装 procps-ng 才有 free 命令
|
||||
if [ -z $ram_size ]; then
|
||||
if ! is_valid_ram_size "$ram_size"; then
|
||||
ram_size_k=$(grep '^MemTotal:' /proc/meminfo | awk '{print $2}')
|
||||
ram_size=$((ram_size_k / 1024 + 64 + 4))
|
||||
fi
|
||||
|
||||
if [ -z $ram_size ] || [ $ram_size -le 0 ]; then
|
||||
if ! is_valid_ram_size "$ram_size"; then
|
||||
error_and_exit "Could not detect RAM size."
|
||||
fi
|
||||
|
||||
@ -2255,6 +2340,10 @@ del_empty_lines() {
|
||||
sed '/^[[:space:]]*$/d'
|
||||
}
|
||||
|
||||
del_comment_lines() {
|
||||
sed '/^[[:space:]]*#/d'
|
||||
}
|
||||
|
||||
trim() {
|
||||
# sed -E -e 's/^[[:space:]]+//' -e 's/[[:space:]]+$//'
|
||||
sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//'
|
||||
@ -2262,16 +2351,23 @@ trim() {
|
||||
|
||||
prompt_password() {
|
||||
info "prompt password"
|
||||
warn false "Leave blank to use a random password."
|
||||
warn false "不填写则使用随机密码"
|
||||
while true; do
|
||||
IFS= read -r -p "Password [$DEFAULT_PASSWORD]: " password
|
||||
IFS= read -r -p "Retype password [$DEFAULT_PASSWORD]: " password_confirm
|
||||
password=${password:-$DEFAULT_PASSWORD}
|
||||
password_confirm=${password_confirm:-$DEFAULT_PASSWORD}
|
||||
if [ -z "$password" ]; then
|
||||
error "Passwords is empty. Try again."
|
||||
elif [ "$password" != "$password_confirm" ]; then
|
||||
error "Passwords don't match. Try again."
|
||||
IFS= read -r -p "Password: " password
|
||||
if [ -n "$password" ]; then
|
||||
IFS= read -r -p "Retype password: " password_confirm
|
||||
if [ "$password" = "$password_confirm" ]; then
|
||||
break
|
||||
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
|
||||
fi
|
||||
done
|
||||
@ -2730,7 +2826,8 @@ install_grub_linux_efi() {
|
||||
info 'download grub efi'
|
||||
|
||||
# fedora 39 的 efi 无法识别 opensuse tumbleweed 的 xfs
|
||||
efi_distro=fedora
|
||||
efi_distro=opensuse
|
||||
|
||||
grub_efi=$(get_grub_efi_filename)
|
||||
|
||||
# 不要用 download.opensuse.org 和 download.fedoraproject.org
|
||||
@ -2745,6 +2842,7 @@ install_grub_linux_efi() {
|
||||
# dl.fedoraproject.org 不支持 ipv6
|
||||
|
||||
if [ "$efi_distro" = fedora ]; then
|
||||
# fedora 43 efi 在 vultr 无法引导 debain 9/10 netboot
|
||||
fedora_ver=$(get_latest_distro_releasever fedora)
|
||||
|
||||
if is_in_china; then
|
||||
@ -2930,7 +3028,7 @@ build_extra_cmdline() {
|
||||
# 会将 extra.xxx=yyy 写入新系统的 /etc/modprobe.d/local.conf
|
||||
# https://answers.launchpad.net/ubuntu/+question/249456
|
||||
# https://salsa.debian.org/installer-team/rootskel/-/blob/master/src/lib/debian-installer-startup.d/S02module-params?ref_type=heads
|
||||
for key in confhome hold force force_cn force_old_windows_setup cloud_image main_disk \
|
||||
for key in confhome hold force_boot_mode force_cn force_old_windows_setup cloud_image main_disk \
|
||||
elts deb_mirror \
|
||||
ssh_port rdp_port web_port allow_ping; do
|
||||
value=${!key}
|
||||
@ -2978,7 +3076,11 @@ build_nextos_cmdline() {
|
||||
if [ $nextos_distro = alpine ]; then
|
||||
nextos_cmdline="alpine_repo=$nextos_repo modloop=$nextos_modloop"
|
||||
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+=" vga=788 video=800x600"
|
||||
nextos_cmdline+=" url=$nextos_ks"
|
||||
nextos_cmdline+=" mirror/http/hostname=${nextos_udeb_mirror%/*}"
|
||||
nextos_cmdline+=" mirror/http/directory=/${nextos_udeb_mirror##*/}"
|
||||
@ -3043,9 +3145,9 @@ mkdir_clear() {
|
||||
|
||||
# 再次运行时,有可能 mount 了 btrfs root,因此先要 umount_all
|
||||
# 但目前不需要 mount ,因此用不到
|
||||
# umount_all $dir
|
||||
rm -rf $dir
|
||||
mkdir -p $dir
|
||||
# umount_all "$dir"
|
||||
rm -rf "$dir"
|
||||
mkdir -p "$dir"
|
||||
}
|
||||
|
||||
mod_initrd_debian_kali() {
|
||||
@ -3054,6 +3156,14 @@ mod_initrd_debian_kali() {
|
||||
sed -Ei 's,&&( onlink=),||\1,' etc/udhcpc/default.script
|
||||
|
||||
# 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 运行我们的脚本
|
||||
netcfg() {
|
||||
#!/bin/sh
|
||||
@ -3065,18 +3175,24 @@ mod_initrd_debian_kali() {
|
||||
|
||||
# 运行 trans.sh,保存配置
|
||||
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 STOP
|
||||
}
|
||||
|
||||
# 直接覆盖 net-retriever,方便调试
|
||||
# curl -Lo /usr/lib/debian-installer/retriever/net-retriever $confhome/net-retriever
|
||||
|
||||
postinst=var/lib/dpkg/info/netcfg.postinst
|
||||
get_function_content netcfg >$postinst
|
||||
get_ip_conf_cmd | insert_into_file $postinst after ": get_ip_conf_cmd"
|
||||
# cat $postinst
|
||||
|
||||
# hack 4
|
||||
# 修改 udeb 依赖
|
||||
|
||||
# 直接覆盖 net-retriever,方便调试
|
||||
# curl -Lo /usr/lib/debian-installer/retriever/net-retriever $confhome/net-retriever
|
||||
|
||||
change_priority() {
|
||||
while IFS= read -r line; do
|
||||
if [[ "$line" = Package:* ]]; then
|
||||
@ -3122,6 +3238,7 @@ partman-xfs
|
||||
rescue-check
|
||||
wpasupplicant-udeb
|
||||
lilo-installer
|
||||
systemd-boot-installer
|
||||
nic-modules-$kver-di
|
||||
nic-pcmcia-modules-$kver-di
|
||||
nic-usb-modules-$kver-di
|
||||
@ -3159,32 +3276,44 @@ EOF
|
||||
# 云内核没有 sata 模块,也没有内嵌,有一个 CONFIG_SATA_HOST=y,libata-$(CONFIG_SATA_HOST) += libata-sata.o
|
||||
# scsi-modules 默认安装(改成可选),包含 nvme.ko(+) 和各种虚拟化驱动(+)
|
||||
|
||||
download_and_extract_udeb() {
|
||||
package=$1
|
||||
extract_dir=$2
|
||||
download_and_extract_deb() {
|
||||
local type=$1
|
||||
local package=$2
|
||||
local extract_dir=$3
|
||||
|
||||
# 获取 udeb 列表
|
||||
udeb_list=$tmp/udeb_list
|
||||
if ! [ -f $udeb_list ]; then
|
||||
# shellcheck disable=SC2154
|
||||
curl -L http://$nextos_udeb_mirror/dists/$nextos_codename/main/debian-installer/binary-$basearch_alt/Packages.gz |
|
||||
zcat | grep 'Filename:' | awk '{print $2}' >$udeb_list
|
||||
case "$type" in
|
||||
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
|
||||
|
||||
# 下载 udeb
|
||||
curl -Lo $tmp/tmp.udeb http://$nextos_udeb_mirror/"$(grep /$package $udeb_list)"
|
||||
# 下载 deb/udeb
|
||||
deb_path=$(grep -F "/${package}_" "$deb_list")
|
||||
curl -Lo $tmp/tmp.deb http://$mirror/"$deb_path"
|
||||
|
||||
if false; then
|
||||
# 使用 dpkg
|
||||
# cygwin 没有 dpkg
|
||||
install_pkg dpkg
|
||||
dpkg -x $tmp/tmp.udeb $extract_dir
|
||||
dpkg -x $tmp/tmp.deb $extract_dir
|
||||
else
|
||||
# 使用 ar tar xz
|
||||
# cygwin 需安装 binutils
|
||||
# centos7 ar 不支持 --output
|
||||
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
|
||||
fi
|
||||
}
|
||||
@ -3228,12 +3357,27 @@ EOF
|
||||
curl -Lo usr/share/keyrings/debian-archive-keyring.gpg https://deb.freexian.com/extended-lts/archive-key.gpg
|
||||
fi
|
||||
|
||||
# 提前下载 sshd
|
||||
# 以便在配置下载源之前就可以启动 sshd
|
||||
mkdir_clear $tmp/sshd
|
||||
download_and_extract_deb udeb openssh-server-udeb $tmp/sshd
|
||||
cp -r $tmp/sshd/* .
|
||||
|
||||
# 提前下载 fdisk
|
||||
# 因为 fdisk-udeb 包含 fdisk 和 sfdisk,提前下载可减少占用
|
||||
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/
|
||||
|
||||
# 下载 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
|
||||
if [ $ram_size -gt 256 ] || is_in_windows; then
|
||||
sed -i '/^pata-modules/d' $net_retriever
|
||||
@ -3264,7 +3408,7 @@ EOF
|
||||
# 但反查也找不到 curl https://deb.debian.org/debian/dists/bookworm/main/Contents-udeb-amd64.gz | zcat | grep xen
|
||||
if [ -n "$extra_drivers" ]; then
|
||||
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
|
||||
|
||||
udeb_drivers_dir=$tmp/scsi/$relative_drivers_dir
|
||||
@ -3600,6 +3744,11 @@ This script is outdated, please download reinstall.sh again.
|
||||
remove_useless_initrd_files
|
||||
fi
|
||||
|
||||
if [ "$hold" = 0 ]; then
|
||||
info 'hold 0'
|
||||
read -r -p 'Press Enter to continue...'
|
||||
fi
|
||||
|
||||
# 重建
|
||||
# 注意要用 cpio -H newc 不要用 cpio -c ,不同版本的 -c 作用不一样,很坑
|
||||
# -c Use the old portable (ASCII) archive format
|
||||
@ -3627,14 +3776,15 @@ remove_useless_initrd_files() {
|
||||
for item in *; do
|
||||
case "$item" in
|
||||
# 甲骨文 arm 用自定义镜像支持设为 mlx5 vf 网卡,且不是 azure 那样显示两个网卡
|
||||
amazon | google | mellanox) ;;
|
||||
# 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)
|
||||
(
|
||||
cd "$item"
|
||||
for sub_item in *; do
|
||||
case "$sub_item" in
|
||||
# 有 e100.ko e1000文件夹 e1000e文件夹
|
||||
e100* | lib* | *vf) ;;
|
||||
e100* | lib* | *vf | idpf) ;;
|
||||
*) rm -rf $sub_item ;;
|
||||
esac
|
||||
done
|
||||
@ -3688,6 +3838,7 @@ get_unix_path() {
|
||||
}
|
||||
|
||||
# 脚本入口
|
||||
|
||||
if mount | grep -q 'tmpfs on / type tmpfs'; then
|
||||
error_and_exit "Can't run this script in Live OS."
|
||||
fi
|
||||
@ -3747,17 +3898,22 @@ for o in ci installer debug minimal allow-ping force-cn help \
|
||||
allow-ping: \
|
||||
commit: \
|
||||
frpc-conf: frpc-config: frpc-toml: \
|
||||
force: \
|
||||
force-boot-mode: \
|
||||
force-old-windows-setup:; do
|
||||
[ -n "$long_opts" ] && long_opts+=,
|
||||
long_opts+=$o
|
||||
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
|
||||
fi
|
||||
|
||||
# /tmp 挂载在内存的话,可能不够空间
|
||||
# 处理 --frpc--toml 时会下载文件,因此在处理参数前就创建临时目录
|
||||
tmp=/reinstall-tmp
|
||||
mkdir_clear "$tmp"
|
||||
|
||||
eval set -- "$opts"
|
||||
# shellcheck disable=SC2034
|
||||
while true; do
|
||||
@ -3769,7 +3925,7 @@ while true; do
|
||||
commit=$2
|
||||
shift 2
|
||||
;;
|
||||
--debug)
|
||||
-x | --debug)
|
||||
set -x
|
||||
shift
|
||||
;;
|
||||
@ -3797,7 +3953,7 @@ while true; do
|
||||
shift
|
||||
;;
|
||||
--hold | --sleep)
|
||||
if ! { [ "$2" = 1 ] || [ "$2" = 2 ]; }; then
|
||||
if ! { [ "$2" = 0 ] || [ "$2" = 1 ] || [ "$2" = 2 ]; }; then
|
||||
error_and_exit "Invalid $1 value: $2"
|
||||
fi
|
||||
hold=$2
|
||||
@ -3806,27 +3962,32 @@ while true; do
|
||||
--frpc-conf | --frpc-config | --frpc-toml)
|
||||
[ -n "$2" ] || error_and_exit "Need value for $1"
|
||||
|
||||
# windows 路径转换
|
||||
frpc_config=$(get_unix_path "$2")
|
||||
|
||||
# alpine busybox 不支持 readlink -m
|
||||
# readlink -m /asfsafasfsaf/fasf
|
||||
# 因此需要先判断路径是否存在
|
||||
|
||||
if ! [ -f "$frpc_config" ]; then
|
||||
error_and_exit "Not a toml file: $2"
|
||||
case "$(to_lower <<<"$2")" in
|
||||
http://* | https://*)
|
||||
frpc_config_url=$2
|
||||
frpc_config=$tmp/frpc_config
|
||||
if ! curl -L "$frpc_config_url" -o "$frpc_config"; then
|
||||
error_and_exit "Can't get frpc config from $frpc_config_url"
|
||||
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")
|
||||
|
||||
shift 2
|
||||
;;
|
||||
--force)
|
||||
--force-boot-mode)
|
||||
if ! { [ "$2" = bios ] || [ "$2" = efi ]; }; then
|
||||
error_and_exit "Invalid $1 value: $2"
|
||||
fi
|
||||
force=$2
|
||||
force_boot_mode=$2
|
||||
shift 2
|
||||
;;
|
||||
--passwd | --password)
|
||||
@ -3854,7 +4015,7 @@ EOF
|
||||
|
||||
# https://manpages.debian.org/testing/openssh-server/authorized_keys.5.en.html#AUTHORIZED_KEYS_FILE_FORMAT
|
||||
is_valid_ssh_key() {
|
||||
grep -qE '^(ecdsa-sha2-nistp(256|384|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"
|
||||
@ -4007,13 +4168,7 @@ fi
|
||||
# 密码
|
||||
if ! is_netboot_xyz && [ -z "$ssh_keys" ] && [ -z "$password" ]; then
|
||||
if is_use_dd; then
|
||||
echo "
|
||||
This password is only used for SSH access to view logs during the installation.
|
||||
Password of the image will NOT modify.
|
||||
|
||||
密码仅用于安装过程中通过 SSH 查看日志。
|
||||
镜像的密码不会被修改。
|
||||
"
|
||||
show_dd_password_tips
|
||||
fi
|
||||
prompt_password
|
||||
fi
|
||||
@ -4021,10 +4176,6 @@ fi
|
||||
# 必备组件
|
||||
install_pkg curl grep
|
||||
|
||||
# /tmp 挂载在内存的话,可能不够空间
|
||||
tmp=/reinstall-tmp
|
||||
mkdir_clear "$tmp"
|
||||
|
||||
# 强制忽略/强制添加 --ci 参数
|
||||
# debian 不强制忽略 ci 留作测试
|
||||
case "$distro" in
|
||||
@ -4433,13 +4584,18 @@ EOF
|
||||
get_function_content load_grubenv_if_not_loaded >$target_cfg
|
||||
|
||||
# 原系统为 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=5
|
||||
menuentry "$(get_entry_name)" --unrestricted {
|
||||
$(! is_in_windows && echo 'insmod lvm')
|
||||
$(is_os_in_btrfs && echo 'set btrfs_relative_path=n')
|
||||
# fedora efi 没有 load_video
|
||||
insmod all_video
|
||||
# set gfxmode=800x600
|
||||
# set gfxpayload=keep
|
||||
# terminal_output gfxterm 在 vultr 上会花屏
|
||||
# terminal_output console
|
||||
search --no-floppy --file --set=root $vmlinuz
|
||||
$linux_cmd $vmlinuz $cmdline
|
||||
$([ -n "$initrds" ] && echo "$initrd_cmd $initrds")
|
||||
@ -4458,8 +4614,8 @@ echo "$distro $releasever"
|
||||
|
||||
case "$distro" in
|
||||
windows) username=administrator ;;
|
||||
dd | netboot.xyz) username= ;;
|
||||
*) username=root ;;
|
||||
netboot.xyz) username= ;;
|
||||
dd | *) username=root ;;
|
||||
esac
|
||||
|
||||
if [ -n "$username" ]; then
|
||||
@ -4476,6 +4632,7 @@ if is_netboot_xyz; then
|
||||
elif is_alpine_live; then
|
||||
echo 'Reboot to start Alpine Live OS.'
|
||||
elif is_use_dd; then
|
||||
show_dd_password_tips
|
||||
echo 'Reboot to start DD.'
|
||||
elif [ "$distro" = fnos ]; then
|
||||
echo "Special note for FNOS:"
|
||||
|
||||
422
trans.sh
422
trans.sh
@ -10,7 +10,7 @@ set -eE
|
||||
|
||||
# 用于判断 reinstall.sh 和 trans.sh 是否兼容
|
||||
# shellcheck disable=SC2034
|
||||
SCRIPT_VERSION=4BACD833-A585-23BA-6CBB-9AA4E08E0003
|
||||
SCRIPT_VERSION=4BACD833-A585-23BA-6CBB-9AA4E08E0004
|
||||
|
||||
TRUE=0
|
||||
FALSE=1
|
||||
@ -87,11 +87,20 @@ apk() {
|
||||
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 的情况下,限制下载大小:
|
||||
# retry 5 command wget | head -c 1048576 会触发 retry,下载 5 次
|
||||
# command wget "$@" --tries=5 | head -c 1048576 不会触发 wget 自带的 retry,只下载 1 次
|
||||
wget() {
|
||||
echo "$@" | grep -o 'http[^ ]*' >&2
|
||||
show_url_in_args "$@" >&2
|
||||
if command wget 2>&1 | grep -q BusyBox; then
|
||||
# busybox wget 没有重试功能
|
||||
# 好像默认永不超时
|
||||
@ -194,7 +203,8 @@ download() {
|
||||
url=$torrent
|
||||
fi
|
||||
|
||||
# intel 禁止了 aria2 下载
|
||||
# intel 禁止了 aria2 下载驱动
|
||||
# intel 禁止了 wget 下载网页内容
|
||||
# 腾讯云 virtio 驱动也禁止了 aria2 下载
|
||||
|
||||
# -o 设置 http 下载文件名
|
||||
@ -203,7 +213,7 @@ download() {
|
||||
-d "$(dirname "$path")" \
|
||||
-o "$(basename "$path")" \
|
||||
-O "1=$(basename "$path")" \
|
||||
-U Wget/1.25.0
|
||||
-U curl/7.54.1
|
||||
|
||||
# opensuse 官方镜像支持 metalink
|
||||
# aira2 无法重命名用 metalink 下载的文件
|
||||
@ -248,8 +258,8 @@ update_part() {
|
||||
}
|
||||
|
||||
is_efi() {
|
||||
if [ -n "$force" ]; then
|
||||
[ "$force" = efi ]
|
||||
if [ -n "$force_boot_mode" ]; then
|
||||
[ "$force_boot_mode" = efi ]
|
||||
else
|
||||
[ -d /sys/firmware/efi/ ]
|
||||
fi
|
||||
@ -294,7 +304,7 @@ setup_websocketd() {
|
||||
pkill websocketd || true
|
||||
# websocketd 遇到 \n 才推送,因此要转换 \r 为 \n
|
||||
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() {
|
||||
@ -313,7 +323,7 @@ get_approximate_ram_size() {
|
||||
setup_web_if_enough_ram() {
|
||||
total_ram=$(get_approximate_ram_size)
|
||||
# 512内存才安装
|
||||
if [ $total_ram -gt 400 ]; then
|
||||
if [ "$total_ram" -ge 400 ]; then
|
||||
# lighttpd 虽然运行占用内存少,但安装占用空间大
|
||||
# setup_lighttpd
|
||||
# setup_nginx
|
||||
@ -442,7 +452,7 @@ EOF
|
||||
}
|
||||
|
||||
umount_all() {
|
||||
dirs="/mnt /os /iso /wim /installer /nbd /nbd-boot /nbd-efi /root /nix"
|
||||
dirs="/mnt /os /iso /wim /installer /nbd /nbd-boot /nbd-efi /nbd-test /root /nix"
|
||||
regex=$(echo "$dirs" | sed 's, ,|,g')
|
||||
if mounts=$(mount | grep -Ew "on $regex" | awk '{print $3}' | tac); then
|
||||
for mount in $mounts; do
|
||||
@ -758,17 +768,19 @@ is_windows_support_rdnss() {
|
||||
[ "$build_ver" -ge 15063 ]
|
||||
}
|
||||
|
||||
get_windows_version_from_dll() {
|
||||
local dll=$1
|
||||
[ -f "$dll" ] || error_and_exit "File not found: $dll"
|
||||
get_windows_version_from_windows_drive() {
|
||||
local os_dir=$1
|
||||
|
||||
apk add pev
|
||||
local ver
|
||||
ver="$(peres -v "$dll" | grep 'Product Version:' | awk '{print $NF}')"
|
||||
echo "Version: $ver" >&2
|
||||
IFS=. read -r nt_ver_major nt_ver_minor build_ver rev_ver _ < <(echo "$ver")
|
||||
apk add hivex pev
|
||||
ntoskrnl_exe=$(find_file_ignore_case $os_dir/Windows/System32/ntoskrnl.exe)
|
||||
hive=$(find_file_ignore_case $os_dir/Windows/System32/config/SOFTWARE)
|
||||
IFS=. read -r nt_ver_major nt_ver_minor _ rev_ver _ \
|
||||
< <(peres -v "$ntoskrnl_exe" | grep 'Product Version:' | awk '{print $NF}')
|
||||
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() {
|
||||
@ -934,11 +946,15 @@ unix2dos() {
|
||||
}
|
||||
|
||||
insert_into_file() {
|
||||
file=$1
|
||||
location=$2
|
||||
regex_to_find=$3
|
||||
local file=$1
|
||||
local location=$2
|
||||
local regex_to_find=$3
|
||||
shift 3
|
||||
|
||||
if ! [ -f "$file" ]; then
|
||||
error_and_exit "File not found: $file"
|
||||
fi
|
||||
|
||||
# 默认 grep -E
|
||||
if [ $# -eq 0 ]; then
|
||||
set -- -E
|
||||
@ -1063,7 +1079,16 @@ EOF
|
||||
echo "iface $ethx inet6 auto" >>$conf_file
|
||||
|
||||
elif is_dhcpv6; then
|
||||
# debian 13 使用 ifupdown + dhcpcd-base
|
||||
# inet/inet6 都配置成 dhcp 时,重启后 dhcpv4 会丢失
|
||||
# 手动 systemctl restart networking 后正常
|
||||
# 删除 dhcpcd-base 安装 isc-dhcp-client(类似 debian 12 升级到 13),轮到 dhcpv6 丢失
|
||||
if { [ "$distro" = debian ] && [ "$releasever" -ge 13 ]; } ||
|
||||
[ "$distro" = kali ]; then
|
||||
echo "iface $ethx inet6 auto" >>$conf_file
|
||||
else
|
||||
echo "iface $ethx inet6 dhcp" >>$conf_file
|
||||
fi
|
||||
|
||||
elif is_staticv6; then
|
||||
get_netconf_to ipv6_addr
|
||||
@ -1604,11 +1629,36 @@ install_nixos() {
|
||||
done
|
||||
fi
|
||||
|
||||
# 备用方案
|
||||
# 1. 从 https://mirror.nju.edu.cn/nix-channels/nixos-25.11/nixexprs.tar.xz 获取
|
||||
# https://github.com/NixOS/nixpkgs/blob/nixos-25.11/pkgs/tools/package-management/nix/default.nix
|
||||
# https://github.com/NixOS/nixpkgs/blob/nixos-25.11/nixos/modules/installer/tools/nix-fallback-paths.nix
|
||||
# 2. 安装最新版 nix,添加 nixos channel 后获取
|
||||
# nix eval -f '<nixpkgs>' --raw 'nixVersions.stable.version' --extra-experimental-features nix-command
|
||||
|
||||
if true; then
|
||||
# nix 版本号使用目标系统里面的
|
||||
download $mirror/nixos-$releasever/store-paths.xz /os/store-paths.xz
|
||||
apk add xz
|
||||
nix_ver=$(xz -dc </os/store-paths.xz | grep -F 'vm-test-run-nix-upgrade' |
|
||||
head -1 | awk -F- '{print $7}' | grep .)
|
||||
rm -f /os/store-paths.xz
|
||||
if is_in_china; then
|
||||
sh_mirror=https://mirror.nju.edu.cn/nix
|
||||
else
|
||||
sh_mirror=https://releases.nixos.org/nix
|
||||
fi
|
||||
sh=$sh_mirror/nix-$nix_ver/install
|
||||
else
|
||||
# 最新版 nix 在 nixos-install 时可能会出问题
|
||||
# https://github.com/bin456789/reinstall/issues/451
|
||||
if is_in_china; then
|
||||
sh=https://mirror.nju.edu.cn/nix/latest/install
|
||||
else
|
||||
sh=https://nixos.org/nix/install
|
||||
fi
|
||||
fi
|
||||
|
||||
apk add xz
|
||||
wget -O- "$sh" | sh -s -- --no-daemon --no-channel-add
|
||||
apk del xz
|
||||
@ -1748,8 +1798,7 @@ EOF
|
||||
# 设置 channel
|
||||
if is_in_china; then
|
||||
nixos-enter --root /os -- \
|
||||
/run/current-system/sw/bin/nix-channel \
|
||||
--add https://mirrors.cernet.edu.cn/nix-channels/nixos-$releasever nixos
|
||||
/run/current-system/sw/bin/nix-channel --add $mirror/nixos-$releasever nixos
|
||||
fi
|
||||
|
||||
# 清理
|
||||
@ -1821,6 +1870,8 @@ add_frpc_systemd_service_if_need() {
|
||||
frpc_url=$(get_frpc_url linux)
|
||||
basename=$(echo "$frpc_url" | awk -F/ '{print $NF}' | sed 's/\.tar\.gz//')
|
||||
download "$frpc_url" "$os_dir/frpc.tar.gz"
|
||||
# busybox tar 不支持 wildcard
|
||||
# tar: */frpc: not found in archive
|
||||
tar xzf "$os_dir/frpc.tar.gz" "$basename/frpc" -O >"$os_dir/usr/local/bin/frpc"
|
||||
rm -f "$os_dir/frpc.tar.gz"
|
||||
chmod a+x "$os_dir/usr/local/bin/frpc"
|
||||
@ -2241,8 +2292,8 @@ aria2c() {
|
||||
apk add coreutils
|
||||
fi
|
||||
|
||||
# 指定 bt 种子时没有链接,因此忽略错误
|
||||
echo "$@" | grep -oE '(http|https|magnet):[^ ]*' || true
|
||||
# 显示 url
|
||||
show_url_in_args "$@" >&2
|
||||
|
||||
# 下载 tracker
|
||||
# 在 sub shell 里面无法保存变量,因此写入到文件
|
||||
@ -2407,8 +2458,8 @@ create_part() {
|
||||
# shellcheck disable=SC2154
|
||||
if [ "$distro" = windows ]; then
|
||||
if ! size_bytes=$(get_link_file_size "$iso"); then
|
||||
# 默认值,最大的iso 23h2 假设 7g
|
||||
size_bytes=$((7 * 1024 * 1024 * 1024))
|
||||
# 默认值,目前最大的 iso 小于 8g
|
||||
size_bytes=$((8 * 1024 * 1024 * 1024))
|
||||
fi
|
||||
|
||||
# 按iso容量计算分区大小
|
||||
@ -2705,14 +2756,6 @@ mount_pseudo_fs() {
|
||||
fi
|
||||
}
|
||||
|
||||
get_yq_name() {
|
||||
if grep -q '3\.1[6789]' /etc/alpine-release; then
|
||||
echo yq
|
||||
else
|
||||
echo yq-go
|
||||
fi
|
||||
}
|
||||
|
||||
create_cloud_init_network_config() {
|
||||
ci_file=$1
|
||||
recognize_static6=${2:-true}
|
||||
@ -2724,7 +2767,7 @@ create_cloud_init_network_config() {
|
||||
mkdir -p "$(dirname "$ci_file")"
|
||||
touch "$ci_file"
|
||||
|
||||
apk add "$(get_yq_name)"
|
||||
apk add yq-go
|
||||
|
||||
need_set_dns4=false
|
||||
need_set_dns6=false
|
||||
@ -2838,7 +2881,7 @@ create_cloud_init_network_config() {
|
||||
yq -i "del(.network.config[$config_id] | select(has(\"address\") | not))" $ci_file
|
||||
fi
|
||||
|
||||
apk del "$(get_yq_name)"
|
||||
apk del yq-go
|
||||
|
||||
# 查看文件
|
||||
info "Cloud-init network config"
|
||||
@ -3201,7 +3244,7 @@ remove_cloud_init() {
|
||||
# disable 会出现一堆提示信息,也无法 disable
|
||||
for unit in $(
|
||||
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
|
||||
# 服务不存在时会报错
|
||||
if chroot $os_dir systemctl -q is-enabled "$unit"; then
|
||||
@ -3218,7 +3261,7 @@ remove_cloud_init() {
|
||||
;;
|
||||
zypper)
|
||||
# 加上 -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)
|
||||
# ubuntu 25.04 开始有 cloud-init-base
|
||||
@ -3244,6 +3287,9 @@ disable_jeos_firstboot() {
|
||||
# 服务不存在时会报错
|
||||
chroot $os_dir systemctl disable "$name.service" 2>/dev/null || true
|
||||
done
|
||||
|
||||
# 可选
|
||||
# chroot $os_dir zypper remove -y -u jeos-firstboot
|
||||
}
|
||||
|
||||
create_network_manager_config() {
|
||||
@ -3328,6 +3374,19 @@ EOF
|
||||
create_network_manager_config /net.cfg "$os_dir"
|
||||
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
|
||||
|
||||
disable_selinux $os_dir
|
||||
@ -3511,7 +3570,7 @@ EOF
|
||||
fi
|
||||
|
||||
# opensuse
|
||||
# 1. kernel-default-base 缺少 nvme 驱动,换成 kernel-default
|
||||
# 1. kernel-default-base 缺少 nvme gve mlx5 mana 驱动,换成 kernel-default
|
||||
# 2. 添加微码+固件
|
||||
# https://documentation.suse.com/smart/virtualization-cloud/html/minimal-vm/index.html
|
||||
if grep -q opensuse $os_dir/etc/os-release; then
|
||||
@ -3523,11 +3582,6 @@ EOF
|
||||
|
||||
disable_jeos_firstboot $os_dir
|
||||
|
||||
# 16.0 需要安装 openssh
|
||||
if ! chroot $os_dir rpm -qi openssh-server; then
|
||||
chroot $os_dir zypper install -y openssh-server
|
||||
fi
|
||||
|
||||
# 禁用 selinux
|
||||
disable_selinux $os_dir
|
||||
|
||||
@ -3596,28 +3650,35 @@ EOF
|
||||
fi
|
||||
|
||||
# rpm -qi 不支持通配符
|
||||
installed_kernel=$(chroot $os_dir rpm -qa 'kernel-*' --qf '%{NAME}\n' | grep -v firmware)
|
||||
if ! [ "$(echo "$installed_kernel" | wc -l)" -eq 1 ]; then
|
||||
error_and_exit "Unexpected kernel installed: $installed_kernel"
|
||||
origin_kernel=$(chroot $os_dir rpm -qa 'kernel-*' --qf '%{NAME}\n' | grep -v firmware)
|
||||
if ! [ "$(echo "$origin_kernel" | wc -l)" -eq 1 ]; then
|
||||
error_and_exit "Unexpected kernel installed: $origin_kernel"
|
||||
fi
|
||||
|
||||
# 15.6 / tumbleweed 自带的是 kernel-default-base
|
||||
# 16.0 自带的是 kernel-default
|
||||
# 不能同时装 kernel-default-base 和 kernel-default
|
||||
|
||||
if ! [ "$installed_kernel" = "$target_kernel" ]; then
|
||||
chroot $os_dir zypper remove -y -u $installed_kernel
|
||||
|
||||
# 16.0 能同时装 kernel-default-base 和 kernel-default
|
||||
# tw 不能同时装 kernel-default-base 和 kernel-default
|
||||
# 因此需要添加 --force-resolution 自动删除 kernel-default-base
|
||||
if ! [ "$origin_kernel" = "$target_kernel" ]; then
|
||||
# x86 必须设置一个密码,否则报错,arm 没有这个问题
|
||||
# Failed to get root password hash
|
||||
# Failed to import /etc/uefi/certs/76B6A6A0.crt
|
||||
# warning: %post(kernel-default-5.14.21-150500.55.83.1.x86_64) scriptlet failed, exit status 255
|
||||
need_password_workaround=false
|
||||
if grep -q '^root:[:!*]' $os_dir/etc/shadow; then
|
||||
need_password_workaround=true
|
||||
fi
|
||||
|
||||
if $need_password_workaround; then
|
||||
echo "root:$(mkpasswd '')" | chroot $os_dir chpasswd -e
|
||||
chroot $os_dir zypper install -y $target_kernel
|
||||
fi
|
||||
# 安装新内核
|
||||
chroot $os_dir zypper install -y --force-resolution $target_kernel
|
||||
# 删除旧内核
|
||||
if chroot $os_dir rpm -q $origin_kernel; then
|
||||
chroot $os_dir zypper remove -y --force-resolution $origin_kernel
|
||||
fi
|
||||
if $need_password_workaround; then
|
||||
chroot $os_dir passwd -d root
|
||||
else
|
||||
chroot $os_dir zypper install -y $target_kernel
|
||||
fi
|
||||
fi
|
||||
|
||||
@ -3737,7 +3798,7 @@ modify_os_on_disk() {
|
||||
# shellcheck disable=SC1090
|
||||
# find_file_ignore_case 也在这个文件里面
|
||||
. <(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; }
|
||||
# 重新挂载为读写、忽略大小写
|
||||
@ -3758,7 +3819,7 @@ modify_os_on_disk() {
|
||||
mount -t ntfs3 -o nocase,rw,force /dev/$part /os
|
||||
fi
|
||||
# 获取版本号,其他地方会用到
|
||||
get_windows_version_from_dll "$ntoskrnl_exe"
|
||||
get_windows_version_from_windows_drive /os
|
||||
modify_windows /os
|
||||
return
|
||||
fi
|
||||
@ -3828,23 +3889,22 @@ change_ssh_conf() {
|
||||
value=$3
|
||||
sub_conf=$4
|
||||
|
||||
if line="^$key .*" && grep -Exq "$line" $os_dir/etc/ssh/sshd_config; then
|
||||
if line="^$key .*" && grep -Exq "$line" $os_dir/etc/ssh/sshd_config 2>/dev/null; then
|
||||
# 如果 sshd_config 存在此 key(非注释状态),则替换
|
||||
sed -Ei "s/$line/$key $value/" $os_dir/etc/ssh/sshd_config
|
||||
elif {
|
||||
elif include_line='^Include.*/etc/ssh/sshd_config.d' &&
|
||||
# arch 没有 /etc/ssh/sshd_config.d/ 文件夹
|
||||
# opensuse tumbleweed 没有 /etc/ssh/sshd_config
|
||||
# 有 /etc/ssh/sshd_config.d/ 文件夹
|
||||
# 有 /usr/etc/ssh/sshd_config
|
||||
grep -q 'Include.*/etc/ssh/sshd_config.d' $os_dir/etc/ssh/sshd_config ||
|
||||
grep -q '^Include.*/etc/ssh/sshd_config.d/' $os_dir/usr/etc/ssh/sshd_config
|
||||
} 2>/dev/null; then
|
||||
{ grep -q "$include_line" $os_dir/etc/ssh/sshd_config ||
|
||||
grep -q "$include_line" $os_dir/usr/etc/ssh/sshd_config; } 2>/dev/null; then
|
||||
mkdir -p $os_dir/etc/ssh/sshd_config.d/
|
||||
echo "$key $value" >"$os_dir/etc/ssh/sshd_config.d/$sub_conf"
|
||||
else
|
||||
# 如果 sshd_config 存在此 key (无论是否已注释),则替换,包括删除注释
|
||||
# 否则追加
|
||||
line="^#?$key .*"
|
||||
line="^[# ]*$key .*"
|
||||
if grep -Exq "$line" $os_dir/etc/ssh/sshd_config; then
|
||||
sed -Ei "s/$line/$key $value/" $os_dir/etc/ssh/sshd_config
|
||||
else
|
||||
@ -3861,7 +3921,17 @@ allow_password_login() {
|
||||
allow_root_password_login() {
|
||||
os_dir=$1
|
||||
|
||||
# opensuse 16/tumbleweed 安装 openssh-server-config-rootlogin
|
||||
# 会生成 /usr/etc/ssh/sshd_config.d/50-permit-root-login.conf
|
||||
# 但是如果用户删除了此文件,包有更新的话,可能会重新创建这个文件?
|
||||
# 因此先不用这个方法
|
||||
if false && [ -f $os_dir/etc/os-release ] &&
|
||||
grep -iq opensuse $os_dir/etc/os-release &&
|
||||
! grep -iq 15.6 $os_dir/etc/os-release; then
|
||||
chroot $os_dir zypper install -y openssh-server-config-rootlogin
|
||||
else
|
||||
change_ssh_conf "$os_dir" PermitRootLogin yes 01-permitrootlogin.conf
|
||||
fi
|
||||
}
|
||||
|
||||
change_ssh_port() {
|
||||
@ -4364,7 +4434,7 @@ install_qcow_by_copy() {
|
||||
fi
|
||||
|
||||
# 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
|
||||
fi
|
||||
|
||||
@ -4438,12 +4508,36 @@ install_qcow_by_copy() {
|
||||
# 安装引导
|
||||
if is_efi; then
|
||||
# 只有centos 和 oracle x86_64 镜像没有efi,其他系统镜像已经从efi分区复制了文件
|
||||
if [ -z "$efi_part" ]; then
|
||||
remove_grub_conflict_files
|
||||
# openeuler 自带 grub2-efi-ia32,此时安装 grub2-efi 提示已经安装了 grub2-efi-ia32,不会继续安装 grub2-efi-x64
|
||||
|
||||
# 假设极端情况,qcow2 制作时,安装 grub2-efi-x64 时没有挂载 efi 分区,那么 efi 文件会在系统分区下
|
||||
# 但我们复制系统分区时挂载了 /boot/efi,因此 efi 文件会正确地复制到 efi 分区
|
||||
# 因此无需判断 qcow2 的 efi 是否是独立分区
|
||||
|
||||
# rhel 镜像没有源,直接 yum install 安装可能会报错
|
||||
# 因此如果已经安装了要用的包就不再运行 yum install
|
||||
need_install=false
|
||||
need_remove_grub_conflict_files=false
|
||||
|
||||
[ "$(uname -m)" = x86_64 ] && arch=x64 || arch=aa64
|
||||
if ! chroot $os_dir rpm -qi grub2-efi-$arch; then
|
||||
need_install=true
|
||||
need_remove_grub_conflict_files=true
|
||||
elif ! chroot $os_dir rpm -qi shim-$arch || ! chroot $os_dir rpm -qi efibootmgr; then
|
||||
need_install=true
|
||||
fi
|
||||
|
||||
if $need_install; then
|
||||
if $need_remove_grub_conflict_files; then
|
||||
remove_grub_conflict_files
|
||||
fi
|
||||
chroot_dnf install efibootmgr grub2-efi-$arch shim-$arch
|
||||
fi
|
||||
# openeuler arm 25.09 云镜像里面的 grubaa64.efi 是用于 mbr 分区表,$root 是 hd0,msdos1
|
||||
# 因此要重新下载 $root 是 hd0,gpt1 的 grubaa64.efi
|
||||
if $need_reinstall_grub_efi; then
|
||||
chroot_dnf reinstall grub2-efi-$arch
|
||||
fi
|
||||
else
|
||||
# bios
|
||||
remove_grub_conflict_files
|
||||
@ -4790,25 +4884,76 @@ EOF
|
||||
lvchange -ay "$vg"
|
||||
fi
|
||||
|
||||
# TODO: 系统分区应该是最后一个分区
|
||||
# 选择最大分区
|
||||
os_part=$(lsblk /dev/nbd0p* --sort SIZE -no NAME,FSTYPE | grep -E 'ext4|xfs' | tail -1 | awk '{print $1}')
|
||||
efi_part=$(lsblk /dev/nbd0p* --sort SIZE -no NAME,PARTTYPE | grep -i "$EFI_UUID" | awk '{print $1}')
|
||||
# 排除前两个,再选择最大分区
|
||||
# almalinux9 boot 分区的类型不是规定的 uuid
|
||||
# openeuler boot 分区是 fat 格式
|
||||
boot_part=$(lsblk /dev/nbd0p* --sort SIZE -no NAME,FSTYPE | grep -E 'ext4|xfs|fat' | awk '{print $1}' |
|
||||
grep -vx "$os_part" | grep -vx "$efi_part" | tail -1 | awk '{print $1}')
|
||||
mount_nouuid() {
|
||||
part_fstype=
|
||||
for arg in "$@"; do
|
||||
case "$arg" in
|
||||
/dev/*)
|
||||
part_fstype=$(lsblk -no FSTYPE "$arg")
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if $is_lvm_image; then
|
||||
os_part="mapper/$os_part"
|
||||
case "$part_fstype" in
|
||||
xfs) mount -o nouuid "$@" ;;
|
||||
*) mount "$@" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
# 可以直接选择最后一个分区为系统分区?
|
||||
# almalinux9 boot 分区的类型不是规定的 uuid
|
||||
# openeuler boot 分区是 vfat 格式
|
||||
# openeuler arm 25.09 是 mbr 分区表, efi boot 是同一个分区,vfat 格式
|
||||
|
||||
info "qcow2 Partitions check"
|
||||
|
||||
# 检测分区表类型
|
||||
partition_table_format=$(get_partition_table_format /dev/nbd0)
|
||||
need_reinstall_grub_efi=false
|
||||
if is_efi && [ "$partition_table_format" = "msdos" ]; then
|
||||
need_reinstall_grub_efi=true
|
||||
fi
|
||||
|
||||
# 通过检测文件判断是什么分区
|
||||
os_part='' boot_part='' efi_part=''
|
||||
mkdir -p /nbd-test
|
||||
for part in $(lsblk /dev/nbd0p* --sort SIZE -no NAME,FSTYPE |
|
||||
grep -E ' (ext4|xfs|fat|vfat)$' | awk '{print $1}' | tac); do
|
||||
mapper_part=$part
|
||||
if $is_lvm_image && [ -e /dev/mapper/$part ]; then
|
||||
mapper_part=mapper/$part
|
||||
fi
|
||||
|
||||
if mount_nouuid -o ro /dev/$mapper_part /nbd-test; then
|
||||
if { ls /nbd-test/etc/os-release || ls /nbd-test/*/etc/os-release; } 2>/dev/null; then
|
||||
os_part=$mapper_part
|
||||
fi
|
||||
# shellcheck disable=SC2010
|
||||
# 当 boot 作为独立分区时,vmlinuz 等文件在根目录
|
||||
# 当 boot 不是独立分区时,vmlinuz 等文件在 /boot 目录
|
||||
if ls /nbd-test/ /nbd-test/boot/ 2>/dev/null | grep -Ei '^(vmlinuz|initrd|initramfs)'; then
|
||||
boot_part=$mapper_part
|
||||
fi
|
||||
# mbr + efi 引导 ,分区表没有 esp guid
|
||||
# 因此需要用 efi 文件判断是否 efi 分区
|
||||
# efi 文件可能在 efi 目录的子目录,子目录层数不定
|
||||
if find /nbd-test/ -type f -ipath '/nbd-test/EFI/*.efi' 2>/dev/null | grep .; then
|
||||
efi_part=$mapper_part
|
||||
fi
|
||||
umount /nbd-test
|
||||
fi
|
||||
done
|
||||
|
||||
info "qcow2 Partitions"
|
||||
lsblk -f /dev/nbd0 -o +PARTTYPE
|
||||
# 显示 OS/EFI/Boot 文件在哪个分区
|
||||
echo "---"
|
||||
echo "Table: $partition_table_format"
|
||||
echo "Part OS: $os_part"
|
||||
echo "Part EFI: $efi_part"
|
||||
echo "Part Boot: $boot_part"
|
||||
echo "---"
|
||||
|
||||
# 分区寻找方式
|
||||
# 系统/分区 cmdline:root fstab:efi
|
||||
@ -4816,25 +4961,16 @@ EOF
|
||||
# ubuntu PARTUUID LABEL=UEFI
|
||||
# 其他el/ol UUID UUID
|
||||
|
||||
# read -r os_part_uuid os_part_label < <(lsblk /dev/$os_part -no UUID,LABEL)
|
||||
os_part_uuid=$(lsblk /dev/$os_part -no UUID)
|
||||
os_part_label=$(lsblk /dev/$os_part -no LABEL)
|
||||
os_part_fstype=$(lsblk /dev/$os_part -no FSTYPE)
|
||||
IFS=, read -r os_part_uuid os_part_label os_part_fstype \
|
||||
< <(lsblk /dev/$os_part -rno UUID,LABEL,FSTYPE | tr ' ' ,)
|
||||
|
||||
if [ -n "$efi_part" ]; then
|
||||
efi_part_uuid=$(lsblk /dev/$efi_part -no UUID)
|
||||
efi_part_label=$(lsblk /dev/$efi_part -no LABEL)
|
||||
IFS=, read -r efi_part_uuid efi_part_label \
|
||||
< <(lsblk /dev/$efi_part -rno UUID,LABEL | tr ' ' ,)
|
||||
fi
|
||||
|
||||
mkdir -p /nbd /nbd-boot /nbd-efi
|
||||
|
||||
mount_nouuid() {
|
||||
case "$os_part_fstype" in
|
||||
ext4) mount "$@" ;;
|
||||
xfs) mount -o nouuid "$@" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
# 使用目标系统的格式化程序
|
||||
# centos8 如果用alpine格式化xfs,grub2-mkconfig和grub2里面都无法识别xfs分区
|
||||
mount_nouuid /dev/$os_part /nbd/
|
||||
@ -4870,16 +5006,17 @@ EOF
|
||||
cp -a /nbd/* /os/
|
||||
umount /nbd/
|
||||
|
||||
# 复制boot分区,如果有
|
||||
if [ -n "$boot_part" ]; then
|
||||
# 复制独立的boot分区,如果有
|
||||
if [ -n "$boot_part" ] && ! [ "$boot_part" = "$os_part" ]; then
|
||||
echo Copying boot partition...
|
||||
mount_nouuid -o ro /dev/$boot_part /nbd-boot/
|
||||
cp -a /nbd-boot/* /os/boot/
|
||||
umount /nbd-boot/
|
||||
fi
|
||||
|
||||
# 复制efi分区,如果有
|
||||
if [ -n "$efi_part" ]; then
|
||||
# 复制独立的efi分区,如果有
|
||||
# 如果 efi 和 boot 是同一个分区,则复制 boot 分区时已经复制了 efi 分区的文件
|
||||
if [ -n "$efi_part" ] && ! [ "$efi_part" = "$os_part" ] && ! [ "$efi_part" = "$boot_part" ]; then
|
||||
echo Copying efi partition...
|
||||
mount -o ro /dev/$efi_part /nbd-efi/
|
||||
cp -a /nbd-efi/* /os/boot/efi/
|
||||
@ -4903,11 +5040,11 @@ EOF
|
||||
umount /os/
|
||||
umount /installer/
|
||||
|
||||
# 如果镜像有efi分区,复制其uuid
|
||||
# 如果镜像有独立的efi分区(包括efi+boot在同一个分区),复制其uuid
|
||||
# 如果有相同uuid的fat分区,则无法挂载
|
||||
# 所以要先复制efi分区,断开nbd再复制uuid
|
||||
# 复制uuid前要取消挂载硬盘 efi 分区
|
||||
if is_efi && [ -n "$efi_part_uuid" ]; then
|
||||
if is_efi && [ -n "$efi_part_uuid" ] && ! [ "$efi_part" = "$os_part" ]; then
|
||||
info "Copy efi partition uuid"
|
||||
apk add mtools
|
||||
mlabel -N "$(echo $efi_part_uuid | sed 's/-//')" -i /dev/$xda*1 ::$efi_part_label
|
||||
@ -5601,8 +5738,7 @@ install_windows() {
|
||||
# 3. 是否支持 sha256
|
||||
# 4. Installation Type
|
||||
wimmount "$iso_install_wim" "$image_index" /wim/
|
||||
ntoskrnl_exe=$(find_file_ignore_case /wim/Windows/System32/ntoskrnl.exe)
|
||||
get_windows_version_from_dll "$ntoskrnl_exe"
|
||||
get_windows_version_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
|
||||
@ -5704,6 +5840,7 @@ install_windows() {
|
||||
# 用注册表无法绕过
|
||||
# https://github.com/pbatard/rufus/issues/1990
|
||||
# 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
|
||||
wiminfo "$install_wim" "$image_index" --image-property WINDOWS/INSTALLATIONTYPE=Server
|
||||
fi
|
||||
@ -5843,39 +5980,81 @@ install_windows() {
|
||||
esac
|
||||
)
|
||||
|
||||
file=$(
|
||||
url=$(
|
||||
case "$product_ver" in
|
||||
'7' | '2008 r2') $support_sha256 &&
|
||||
'7' | '2008 r2')
|
||||
# 现在官网只有 25.0
|
||||
# 25.0 比 24.5 只更新了 ProSet 软件,驱动相同
|
||||
echo 18713/eng/prowin${arch_intel}legacy.exe || # 25.0 有部分文件是 sha256 签名
|
||||
echo 29323/eng/prowin${arch_intel}legacy.exe ;; # 24.3 sha1 签名
|
||||
'8') echo 21642/eng/prowin${arch_intel}.exe ;;
|
||||
'8.1') echo 764813/Wired_driver_27.8_${arch_intel}.zip ;;
|
||||
'2012' | '2012 r2') echo 785805/Wired_driver_28.2_${arch_intel}.zip ;;
|
||||
# 25.0 有部分文件是 sha256 签名
|
||||
# 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
|
||||
# 但已被删除,原因不明
|
||||
# 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 相比 22.7.1,可能有些老设备不支持了,但我们不管了
|
||||
echo https://downloadmirror.intel.com/764813/Wired_driver_27.8_${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
|
||||
32) echo 849483/Wired_driver_30.0.1_${arch_intel}.zip ;;
|
||||
x64) echo 861427/Wired_driver_30.3_${arch_intel}.zip ;;
|
||||
32)
|
||||
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
|
||||
)
|
||||
|
||||
web_archive=$(
|
||||
case "$product_ver" in
|
||||
'8') echo https://web.archive.org/web/20250501043104/ ;;
|
||||
esac
|
||||
)
|
||||
|
||||
# 注意 intel 禁止了 aria2 下载
|
||||
download ${web_archive}https://downloadmirror.intel.com/$file $drv/intel.zip
|
||||
download "$url" $drv/intel.zip
|
||||
|
||||
# inf 可能是 UTF-16 LE?因此用 rg 搜索
|
||||
# 用 busybox unzip 解压 win10 驱动时,路径和文件名会粘在一起
|
||||
# 但解压 28.0 驱动时,依然会出现这个问题
|
||||
# 因此需要 convert_backslashes
|
||||
apk add unzip ripgrep
|
||||
|
||||
# https://superuser.com/questions/1382839/zip-files-expand-with-backslashes-on-linux-no-subdirectories
|
||||
convert_backslashes() {
|
||||
for file in "$1"/*\\*; do
|
||||
if [ -f "$file" ]; then
|
||||
target="${file//\\//}"
|
||||
mkdir -p "${target%/*}"
|
||||
mv -v "$file" "$target"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# win7 驱动是 .exe 解压不会报错
|
||||
# win10 驱动是 .zip 解压反而会报错,目测 zip 文件有问题
|
||||
# 在 windows 下解压 win8 的驱动会提示 checksum 错误
|
||||
unzip -o -d $drv/intel/ $drv/intel.zip || true
|
||||
convert_backslashes $drv/intel
|
||||
|
||||
is_have_inf_in_intel_dir() {
|
||||
find $drv/intel -ipath "*/*.inf" | grep . >/dev/null
|
||||
}
|
||||
|
||||
# Wired_driver_28.0_x64.zip 需要二次解压
|
||||
if ! is_have_inf_in_intel_dir; then
|
||||
unzip -o -d $drv/intel/ $drv/intel/Wired_driver_*.exe || true
|
||||
convert_backslashes $drv/intel
|
||||
fi
|
||||
|
||||
# 由于上面使用了 || true,因此确认下解压后是否有 inf 文件
|
||||
if ! is_have_inf_in_intel_dir; then
|
||||
error_and_exit "No .inf file found in intel driver package"
|
||||
fi
|
||||
|
||||
# Vista RTM 版本号是 6000 NDIS 6.0
|
||||
# 2008 RTM 版本号是 6001 NDIS 6.1
|
||||
@ -6439,12 +6618,17 @@ EOF
|
||||
done
|
||||
|
||||
if ! $is_gen11 && [ "$build_ver" -ge 19041 ]; then
|
||||
url=https://downloadmirror.intel.com/849939/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
|
||||
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
|
||||
error_and_exit "can't find suitable vmd driver"
|
||||
fi
|
||||
local url
|
||||
url=$(wget -U curl/7.54.1 "$page" -O- |
|
||||
grep -Eio -m1 "\"https://.+/SetupRST\.exe\"" | tr -d '"' | grep .)
|
||||
|
||||
# 注意 intel 禁止了 aria2 下载
|
||||
download $url $drv/SetupRST.exe
|
||||
|
||||
@ -12,56 +12,90 @@ rem set ipv6_dns2=::2
|
||||
|
||||
@echo off
|
||||
mode con cp select=437 >nul
|
||||
setlocal EnableDelayedExpansion
|
||||
|
||||
rem 禁用 IPv6 地址标识符的随机化,防止 IPv6 和后台面板不一致
|
||||
netsh interface ipv6 set global randomizeidentifiers=disabled
|
||||
|
||||
rem 检查是否定义了 MAC 地址
|
||||
if defined mac_addr (
|
||||
for /f %%a in ('wmic nic where "MACAddress='%mac_addr%'" get InterfaceIndex ^| findstr [0-9]') do set id=%%a
|
||||
if defined id (
|
||||
if not defined mac_addr goto :del
|
||||
|
||||
rem vista 没有自带 powershell
|
||||
rem win11 24h2 安装后有 wmic,但是过一段时间会自动删除,因此有的 dd 镜像没有 wmic
|
||||
if exist "%windir%\system32\wbem\wmic.exe" (
|
||||
rem wmic 换行符是 \r\r\n
|
||||
rem 虽然这里用了 findstr 全字匹配 ,但是结尾还是有 \r
|
||||
for /f "tokens=2 delims==" %%a in (
|
||||
'wmic nic where "MACAddress='%mac_addr%'" get InterfaceIndex /format:list ^| findstr "^InterfaceIndex=[0-9][0-9]*$"'
|
||||
) do set id=%%a
|
||||
)
|
||||
|
||||
if not defined id (
|
||||
for /f %%a in ('powershell -NoLogo -NoProfile -NonInteractive -ExecutionPolicy Bypass ^
|
||||
-Command "(Get-WmiObject Win32_NetworkAdapter | Where-Object { $_.MACAddress -eq '%mac_addr%' }).InterfaceIndex" ^| findstr "^[0-9][0-9]*$"'
|
||||
) do set id=%%a
|
||||
)
|
||||
|
||||
if not defined id (
|
||||
for /f %%a in ('powershell -NoLogo -NoProfile -NonInteractive -ExecutionPolicy Bypass ^
|
||||
-Command "(Get-CimInstance Win32_NetworkAdapter | Where-Object { $_.MACAddress -eq '%mac_addr%' }).InterfaceIndex" ^| findstr "^[0-9][0-9]*$"'
|
||||
) do set id=%%a
|
||||
)
|
||||
|
||||
if defined id (
|
||||
rem 配置静态 IPv4 地址和网关
|
||||
if defined ipv4_addr if defined ipv4_gateway (
|
||||
rem 如果使用了 setlocal EnableDelayedExpansion
|
||||
rem netsh interface ipv4 set address !id! static %ipv4_addr% gateway=%ipv4_gateway% gwmetric=0
|
||||
rem !id! 变量最后有 \r 会导致语句不正确
|
||||
rem %id% 变量则没有这个问题
|
||||
|
||||
rem gwmetric 默认值为 1,自动跃点需设为 0
|
||||
netsh interface ipv4 set address !id! static !ipv4_addr! gateway=!ipv4_gateway! gwmetric=0
|
||||
netsh interface ipv4 set address %id% static %ipv4_addr% gateway=%ipv4_gateway% gwmetric=0
|
||||
)
|
||||
|
||||
rem 配置静态 IPv4 DNS 服务器
|
||||
for %%i in (1, 2) do (
|
||||
if defined ipv4_dns%%i (
|
||||
netsh interface ipv4 add | findstr "dnsservers"
|
||||
netsh interface ipv4 add | findstr "dnsservers" >nul
|
||||
if ErrorLevel 1 (
|
||||
rem vista
|
||||
netsh interface ipv4 add dnsserver !id! !ipv4_dns%%i! %%i
|
||||
setlocal EnableDelayedExpansion
|
||||
netsh interface ipv4 add dnsserver %id% !ipv4_dns%%i! %%i
|
||||
endlocal
|
||||
) else (
|
||||
rem win7
|
||||
netsh interface ipv4 add dnsservers !id! !ipv4_dns%%i! %%i no
|
||||
setlocal EnableDelayedExpansion
|
||||
netsh interface ipv4 add dnsservers %id% !ipv4_dns%%i! %%i no
|
||||
endlocal
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
rem 配置 IPv6 地址和网关
|
||||
if defined ipv6_addr if defined ipv6_gateway (
|
||||
netsh interface ipv6 set address !id! !ipv6_addr!
|
||||
netsh interface ipv6 add route prefix=::/0 !id! !ipv6_gateway!
|
||||
netsh interface ipv6 set address %id% %ipv6_addr%
|
||||
netsh interface ipv6 add route prefix=::/0 %id% %ipv6_gateway%
|
||||
)
|
||||
|
||||
rem 配置 IPv6 DNS 服务器
|
||||
for %%i in (1, 2) do (
|
||||
if defined ipv6_dns%%i (
|
||||
netsh interface ipv6 add | findstr "dnsservers"
|
||||
netsh interface ipv6 add | findstr "dnsservers" >nul
|
||||
if ErrorLevel 1 (
|
||||
rem vista
|
||||
netsh interface ipv6 add dnsserver !id! !ipv6_dns%%i! %%i
|
||||
setlocal EnableDelayedExpansion
|
||||
netsh interface ipv6 add dnsserver %id% !ipv6_dns%%i! %%i
|
||||
endlocal
|
||||
) else (
|
||||
rem win7
|
||||
netsh interface ipv6 add dnsservers !id! !ipv6_dns%%i! %%i no
|
||||
)
|
||||
setlocal EnableDelayedExpansion
|
||||
netsh interface ipv6 add dnsservers %id% !ipv6_dns%%i! %%i no
|
||||
endlocal
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
:del
|
||||
rem 删除此脚本
|
||||
del "%~f0"
|
||||
|
||||
Reference in New Issue
Block a user