mirror of
https://github.com/bin456789/reinstall.git
synced 2026-02-04 09:04:18 +08:00
Compare commits
8 Commits
1a3d8b4f3b
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| f2cfe672d1 | |||
| 0cc3fc77d6 | |||
| 6a35bf681a | |||
| e7f8802bdd | |||
| 259bcf7275 | |||
| 90becc9850 | |||
| 85e2661161 | |||
| 74d9524a9b |
13
README.en.md
13
README.en.md
@ -4,7 +4,8 @@
|
|||||||
|
|
||||||
[](https://app.codacy.com/gh/bin456789/reinstall/dashboard)
|
[](https://app.codacy.com/gh/bin456789/reinstall/dashboard)
|
||||||
[](https://www.codefactor.io/repository/github/bin456789/reinstall)
|
[](https://www.codefactor.io/repository/github/bin456789/reinstall)
|
||||||
[](https://github.com/XAMPPRocky/tokei_rs)
|
[](https://github.com/aschey/vercel-tokei)
|
||||||
|
<!-- [](https://github.com/XAMPPRocky/tokei_rs) -->
|
||||||
|
|
||||||
One-Click system reinstallation script for VPS [中文](README.md)
|
One-Click system reinstallation script for VPS [中文](README.md)
|
||||||
|
|
||||||
@ -34,7 +35,7 @@ If this helped you, you can buy me a milk tea.
|
|||||||
- [Download](#download-current-system-is--linux)
|
- [Download](#download-current-system-is--linux)
|
||||||
- [Feature 1. One-click reinstallation to Linux](#feature-1-install--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 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 3. One-click reboot to Alpine Live OS](#feature-3-reboot-to--alpine-live-os)
|
||||||
- [Feature 4. One-click reboot to netboot.xyz](#feature-4-reboot-to--netbootxyz)
|
- [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)
|
- [Feature 5. One-click reinstallation to Windows](#feature-5-install--windows-iso)
|
||||||
|
|
||||||
@ -149,7 +150,7 @@ certutil -urlcache -f -split https://cnb.cool/bin456789/reinstall/-/git/raw/main
|
|||||||
- When installing the latest version, the version number does not need to be specified.
|
- When installing the latest version, the version number does not need to be specified.
|
||||||
- Maximizes disk space usage: no boot partition (except for Fedora) and no swap partition.
|
- Maximizes disk space usage: no boot partition (except for Fedora) and no swap partition.
|
||||||
- Automatically selects different optimized kernels based on machine type, such as `Cloud` or `HWE` kernels.
|
- Automatically selects different optimized kernels based on machine type, such as `Cloud` or `HWE` kernels.
|
||||||
- When installing Red Hat, you must provide the `qcow2` image link obtained from <https://access.redhat.com/downloads/content/rhel>. You can also install other RHEL-based OS, such as `Alibaba Cloud Linux` and `TencentOS Server`.
|
- When installing Red Hat, you must provide the `qcow2` image link obtained from <https://access.redhat.com/downloads/content/rhel>. You can also install `qcow2` of other RHEL-based OS, such as `Alibaba Cloud Linux` and `TencentOS Server`.
|
||||||
- After reinstallation, if you need to change the SSH port or switch to key-based login, make sure to also modify the files inside `/etc/ssh/sshd_config.d/`.
|
- After reinstallation, if you need to change the SSH port or switch to key-based login, make sure to also modify the files inside `/etc/ssh/sshd_config.d/`.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@ -258,7 +259,7 @@ bash reinstall.sh dd --img "https://example.com/xxx.xz"
|
|||||||
>
|
>
|
||||||
> Or Run `/trans.sh alpine` to automatically recover to Alpine Linux.
|
> Or Run `/trans.sh alpine` to automatically recover to Alpine Linux.
|
||||||
|
|
||||||
### Feature 3: Reboot to <img width="16" height="16" src="https://www.alpinelinux.org/alpine-logo.ico" /> Alpine Live OS (RAM OS)
|
### Feature 3: Reboot to <img width="16" height="16" src="https://www.alpinelinux.org/alpine-logo.ico" /> Alpine Live OS
|
||||||
|
|
||||||
- You can use SSH to backup/restore disk, manually perform DD operations, partition modifications, manual Alpine installation, and other operations.
|
- You can use SSH to backup/restore disk, manually perform DD operations, partition modifications, manual Alpine installation, and other operations.
|
||||||
- Username `root`. The script prompts for a password. If left blank, a random one is generated.
|
- Username `root`. The script prompts for a password. If left blank, a random one is generated.
|
||||||
@ -266,7 +267,7 @@ bash reinstall.sh dd --img "https://example.com/xxx.xz"
|
|||||||
> [!TIP]
|
> [!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.
|
> 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.
|
> If the user does not damage the original system during manual operation, rebooting will return to the original system.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@ -287,7 +288,7 @@ bash reinstall.sh alpine --hold 1
|
|||||||
> [!TIP]
|
> [!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.
|
> 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.
|
> If the user does not damage the original system during manual operation, rebooting will return to the original system.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|||||||
@ -4,7 +4,8 @@
|
|||||||
|
|
||||||
[](https://app.codacy.com/gh/bin456789/reinstall/dashboard)
|
[](https://app.codacy.com/gh/bin456789/reinstall/dashboard)
|
||||||
[](https://www.codefactor.io/repository/github/bin456789/reinstall)
|
[](https://www.codefactor.io/repository/github/bin456789/reinstall)
|
||||||
[](https://github.com/XAMPPRocky/tokei_rs)
|
[](https://github.com/aschey/vercel-tokei)
|
||||||
|
<!-- [](https://github.com/XAMPPRocky/tokei_rs) -->
|
||||||
|
|
||||||
一键 VPS 系统重装脚本 [English](README.en.md)
|
一键 VPS 系统重装脚本 [English](README.en.md)
|
||||||
|
|
||||||
@ -149,7 +150,7 @@ certutil -urlcache -f -split https://cnb.cool/bin456789/reinstall/-/git/raw/main
|
|||||||
- 安装最新版可不输入版本号
|
- 安装最新版可不输入版本号
|
||||||
- 最大化利用磁盘空间:不含 boot 分区(Fedora 例外),不含 swap 分区
|
- 最大化利用磁盘空间:不含 boot 分区(Fedora 例外),不含 swap 分区
|
||||||
- 自动根据机器类型选择不同的优化内核,例如 `Cloud`、`HWE` 内核
|
- 自动根据机器类型选择不同的优化内核,例如 `Cloud`、`HWE` 内核
|
||||||
- 安装 Red Hat 时需填写 <https://access.redhat.com/downloads/content/rhel> 得到的 `qcow2` 镜像链接,也可以安装其它类 RHEL 系统,例如 `Alibaba Cloud Linux` 和 `TencentOS Server`
|
- 安装 Red Hat 时需填写 <https://access.redhat.com/downloads/content/rhel> 得到的 `qcow2` 镜像链接,也可以安装其它类 RHEL 系统的 `qcow2`,例如 `Alibaba Cloud Linux` 和 `TencentOS Server`
|
||||||
- 重装后如需修改 SSH 端口或者改成密钥登录,注意还要修改 `/etc/ssh/sshd_config.d/` 里面的文件
|
- 重装后如需修改 SSH 端口或者改成密钥登录,注意还要修改 `/etc/ssh/sshd_config.d/` 里面的文件
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|||||||
@ -345,14 +345,14 @@ EOF
|
|||||||
db_progress INFO netcfg/link_detect_progress
|
db_progress INFO netcfg/link_detect_progress
|
||||||
else
|
else
|
||||||
# alpine
|
# alpine
|
||||||
# h3c 移动云电脑使用 udhcpc 会重复提示 sending select,无法获得 ipv6
|
# h3c 移动云电脑使用 udhcpc 会重复提示 sending select,因此添加 timeout 强制结束进程
|
||||||
# dhcpcd 会配置租约时间,过期会移除 IP,但我们的没有在后台运行 dhcpcd ,因此用 udhcpc
|
# dhcpcd 会配置租约时间,过期会移除 IP,但我们的没有在后台运行 dhcpcd ,因此用 udhcpc
|
||||||
method=udhcpc
|
method=udhcpc
|
||||||
|
|
||||||
case "$method" in
|
case "$method" in
|
||||||
udhcpc)
|
udhcpc)
|
||||||
udhcpc -i "$ethx" -f -q -n || true
|
timeout $DHCP_TIMEOUT udhcpc -i "$ethx" -f -q -n || true
|
||||||
udhcpc6 -i "$ethx" -f -q -n || true
|
timeout $DHCP_TIMEOUT udhcpc6 -i "$ethx" -f -q -n || true
|
||||||
sleep $DNS_FILE_TIMEOUT # 好像不用等待写入 dns,但是以防万一
|
sleep $DNS_FILE_TIMEOUT # 好像不用等待写入 dns,但是以防万一
|
||||||
;;
|
;;
|
||||||
dhcpcd)
|
dhcpcd)
|
||||||
|
|||||||
47
reinstall.sh
47
reinstall.sh
@ -1086,7 +1086,10 @@ get_windows_iso_link() {
|
|||||||
if [ -n "$label_msdl" ]; then
|
if [ -n "$label_msdl" ]; then
|
||||||
iso=$(curl -L "$page_url" | grep -ioP 'https://[^ ]+?#[0-9]+' | head -1 | grep .)
|
iso=$(curl -L "$page_url" | grep -ioP 'https://[^ ]+?#[0-9]+' | head -1 | grep .)
|
||||||
else
|
else
|
||||||
curl -L "$page_url" | grep -ioP 'https://[^ ]+?.(iso|img)' >$tmp/win.list
|
curl -L "$page_url" |
|
||||||
|
tr -d '\n' | sed -e 's,<a ,\n<a ,g' -e 's,</a>,</a>\n,g' | # 使每个 <a></a> 占一行
|
||||||
|
grep -Ei '\.(iso|img)</a>$' | # 找出是 iso 或 img 的行
|
||||||
|
sed -E 's,<a href="?([^" ]+)"?.+>(.+)</a>,\2 \1,' >$tmp/win.list # 提取文件名和链接
|
||||||
|
|
||||||
# 如果不是 ltsc ,应该先去除 ltsc 链接,否则最终链接有 ltsc 的
|
# 如果不是 ltsc ,应该先去除 ltsc 链接,否则最终链接有 ltsc 的
|
||||||
# 例如查找 windows 10 iot enterprise,会得到
|
# 例如查找 windows 10 iot enterprise,会得到
|
||||||
@ -1104,10 +1107,14 @@ get_windows_iso_link() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get_shortest_line() {
|
get_shortest_line() {
|
||||||
# awk '{print length($0), $0}' | sort -n | head -1 | awk '{print $2}'
|
|
||||||
awk '(NR == 1 || length($0) < length(shortest)) { shortest = $0 } END { print shortest }'
|
awk '(NR == 1 || length($0) < length(shortest)) { shortest = $0 } END { print shortest }'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get_shortest_line_by_field() {
|
||||||
|
local field=$1
|
||||||
|
awk "(NR == 1 || length(\$$field) < length(field)) { line = \$0; field = \$$field } END { print line }"
|
||||||
|
}
|
||||||
|
|
||||||
get_windows_iso_link_inner() {
|
get_windows_iso_link_inner() {
|
||||||
regexs=()
|
regexs=()
|
||||||
|
|
||||||
@ -1139,7 +1146,9 @@ get_windows_iso_link_inner() {
|
|||||||
regex=${regex// /_}
|
regex=${regex// /_}
|
||||||
|
|
||||||
echo "looking for: $regex" >&2
|
echo "looking for: $regex" >&2
|
||||||
if iso=$(grep -Ei "/$regex" "$tmp/win.list" | get_shortest_line | grep .); then
|
if line=$(grep -Ei "^$regex " "$tmp/win.list" | get_shortest_line_by_field 1 | grep .) &&
|
||||||
|
iso=$(awk '{print $2}' <<<"$line" | grep .); then
|
||||||
|
echo "Selected: $line" >&2
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
@ -1512,7 +1521,9 @@ Continue?
|
|||||||
}
|
}
|
||||||
|
|
||||||
setos_windows() {
|
setos_windows() {
|
||||||
|
auto_find_iso=false
|
||||||
if [ -z "$iso" ]; then
|
if [ -z "$iso" ]; then
|
||||||
|
auto_find_iso=true
|
||||||
# 查找时将 windows longhorn serverdatacenter 改成 windows server 2008 serverdatacenter
|
# 查找时将 windows longhorn serverdatacenter 改成 windows server 2008 serverdatacenter
|
||||||
image_name=${image_name/windows longhorn server/windows server 2008 server}
|
image_name=${image_name/windows longhorn server/windows server 2008 server}
|
||||||
echo "iso url is not set. Attempting to find it automatically."
|
echo "iso url is not set. Attempting to find it automatically."
|
||||||
@ -1526,10 +1537,13 @@ Continue?
|
|||||||
|
|
||||||
if [[ "$iso" = magnet:* ]]; then
|
if [[ "$iso" = magnet:* ]]; then
|
||||||
: # 不测试磁力链接
|
: # 不测试磁力链接
|
||||||
|
else
|
||||||
|
iso_is_tested=false
|
||||||
|
if $auto_find_iso; then
|
||||||
|
if test_url_grace "$iso" iso 2>/dev/null; then
|
||||||
|
iso_is_tested=true
|
||||||
else
|
else
|
||||||
# 需要用户输入 massgrave.dev 直链
|
# 需要用户输入 massgrave.dev 直链
|
||||||
if grep -Eiq '\.massgrave\.dev/.*\.(iso|img)$' <<<"$iso" ||
|
|
||||||
grep -Eiq '\.gravesoft\.dev/#[0-9]+$' <<<"$iso"; then
|
|
||||||
info "Set Direct link"
|
info "Set Direct link"
|
||||||
# MobaXterm 不支持
|
# MobaXterm 不支持
|
||||||
# printf '\e]8;;http://example.com\e\\This is a link\e]8;;\e\\\n'
|
# printf '\e]8;;http://example.com\e\\This is a link\e]8;;\e\\\n'
|
||||||
@ -1545,9 +1559,11 @@ Continue?
|
|||||||
error_and_exit "ISO Link is empty."
|
error_and_exit "ISO Link is empty."
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
# 测试是否是 iso
|
if ! $iso_is_tested; then
|
||||||
test_url "$iso" iso
|
test_url "$iso" iso
|
||||||
|
fi
|
||||||
|
|
||||||
# 判断 iso 架构是否兼容
|
# 判断 iso 架构是否兼容
|
||||||
# https://gitlab.com/libosinfo/osinfo-db/-/tree/main/data/os/microsoft.com?ref_type=heads
|
# https://gitlab.com/libosinfo/osinfo-db/-/tree/main/data/os/microsoft.com?ref_type=heads
|
||||||
@ -1622,15 +1638,13 @@ Continue with DD?
|
|||||||
}
|
}
|
||||||
|
|
||||||
setos_fnos() {
|
setos_fnos() {
|
||||||
if [ "$basearch" = aarch64 ]; then
|
|
||||||
error_and_exit "FNOS not supports ARM."
|
|
||||||
fi
|
|
||||||
|
|
||||||
# 系统盘大小
|
# 系统盘大小
|
||||||
min=8
|
min=8
|
||||||
default=8
|
default=8
|
||||||
|
echo "请输入系统分区大小,最小 $min GB,但可能无法更新系统。"
|
||||||
|
echo "Please input System Partition Size. Minimal is $min GB but may not be able to do system updates."
|
||||||
while true; do
|
while true; do
|
||||||
IFS= read -r -p "Type System Partition Size in GB. Minimal $min GB. [$default]: " input
|
IFS= read -r -p "Size in GB [$default]: " input
|
||||||
input=${input:-$default}
|
input=${input:-$default}
|
||||||
if ! { is_digit "$input" && [ "$input" -ge "$min" ]; }; then
|
if ! { is_digit "$input" && [ "$input" -ge "$min" ]; }; then
|
||||||
error "Invalid Size. Please Try again."
|
error "Invalid Size. Please Try again."
|
||||||
@ -1640,7 +1654,15 @@ Continue with DD?
|
|||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
iso=$(curl -L https://fnnas.com/ | grep -o 'https://[^"]*\.iso' | head -1 | grep .)
|
if [ "$basearch" = aarch64 ]; then
|
||||||
|
if [ -z "$iso" ]; then
|
||||||
|
IFS= read -r -p "ISO Link: " iso
|
||||||
|
if [ -z "$iso" ]; then
|
||||||
|
error_and_exit "ISO Link is empty."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
iso=$(curl -L https://fnnas.com/ | grep -o -m1 'https://[^"]*\.iso')
|
||||||
|
|
||||||
# curl 7.82.0+
|
# curl 7.82.0+
|
||||||
# curl -L --json '{"url":"'$iso'"}' https://www.fnnas.com/api/download-sign
|
# curl -L --json '{"url":"'$iso'"}' https://www.fnnas.com/api/download-sign
|
||||||
@ -1650,6 +1672,7 @@ Continue with DD?
|
|||||||
-H 'Content-Type: application/json' \
|
-H 'Content-Type: application/json' \
|
||||||
https://www.fnnas.com/api/download-sign |
|
https://www.fnnas.com/api/download-sign |
|
||||||
grep -o 'https://[^"]*')
|
grep -o 'https://[^"]*')
|
||||||
|
fi
|
||||||
|
|
||||||
test_url "$iso" iso
|
test_url "$iso" iso
|
||||||
eval "${step}_iso='$iso'"
|
eval "${step}_iso='$iso'"
|
||||||
|
|||||||
175
trans.sh
175
trans.sh
@ -414,23 +414,31 @@ extract_env_from_cmdline() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ensure_service_started() {
|
ensure_service_started() {
|
||||||
service=$1
|
local service=$1
|
||||||
|
|
||||||
if ! rc-service -q $service status; then
|
if ! rc-service -q "$service" start; then
|
||||||
if ! retry 5 rc-service -q $service start; then
|
for i in $(seq 10); do
|
||||||
error_and_exit "Failed to start $service."
|
if [ "$service" = modloop ]; then
|
||||||
|
# 避免有时 modloop 下载不完整导致报错
|
||||||
|
# * Failed to verify signature of !
|
||||||
|
# mount: mounting /dev/loop0 on /.modloop failed: Invalid argument
|
||||||
|
rm -f /lib/modloop-lts /lib/modloop-virt
|
||||||
fi
|
fi
|
||||||
|
if rc-service -q "$service" start; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
sleep 5
|
||||||
|
done
|
||||||
|
error_and_exit "Failed to start $service."
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
ensure_service_stopped() {
|
ensure_service_stopped() {
|
||||||
service=$1
|
local service=$1
|
||||||
|
|
||||||
if rc-service -q $service status; then
|
if ! retry 10 5 rc-service -q "$service" stop; then
|
||||||
if ! retry 5 rc-service -q $service stop; then
|
|
||||||
error_and_exit "Failed to stop $service."
|
error_and_exit "Failed to stop $service."
|
||||||
fi
|
fi
|
||||||
fi
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mod_motd() {
|
mod_motd() {
|
||||||
@ -2431,7 +2439,7 @@ get_disk_logic_sector_size() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
is_4kn() {
|
is_4kn() {
|
||||||
[ "$(blockdev --getss "$1")" = 4096 ]
|
[ "$(blockdev --getss "/dev/$xda")" = 4096 ]
|
||||||
}
|
}
|
||||||
|
|
||||||
is_xda_gt_2t() {
|
is_xda_gt_2t() {
|
||||||
@ -2523,15 +2531,18 @@ create_part() {
|
|||||||
sector_size=$(get_disk_logic_sector_size /dev/$xda)
|
sector_size=$(get_disk_logic_sector_size /dev/$xda)
|
||||||
total_sector_count=$(get_disk_sector_count /dev/$xda)
|
total_sector_count=$(get_disk_sector_count /dev/$xda)
|
||||||
|
|
||||||
# 截止最后一个分区的总扇区数(也就是总硬盘扇区数 - 备份分区表扇区数)
|
# 截止最后一个分区的总扇区数(也就是总硬盘扇区数 - 备份分区表扇区数 - 备份 GPT Header)
|
||||||
if is_efi; then
|
if ! is_efi && ! is_xda_gt_2t; then
|
||||||
total_sector_count_except_backup_gpt=$((total_sector_count - 33))
|
# mbr
|
||||||
else
|
|
||||||
total_sector_count_except_backup_gpt=$total_sector_count
|
total_sector_count_except_backup_gpt=$total_sector_count
|
||||||
|
elif is_4kn; then
|
||||||
|
total_sector_count_except_backup_gpt=$((total_sector_count - 4 - 1))
|
||||||
|
else
|
||||||
|
total_sector_count_except_backup_gpt=$((total_sector_count - 32 - 1))
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 向下取整 MiB
|
# 向下取整 MiB
|
||||||
# gpt 最后 33 个扇区是备份分区表,不可用
|
# gpt 最后 33 (512n/512e) 或 5 (4Kn) 个扇区是备份分区表,不可用
|
||||||
# parted 结束位置填 100% 时也会忽略最后不足 1MiB 的部分,我们模仿它
|
# parted 结束位置填 100% 时也会忽略最后不足 1MiB 的部分,我们模仿它
|
||||||
max_can_use_m=$((total_sector_count_except_backup_gpt * sector_size / 1024 / 1024))
|
max_can_use_m=$((total_sector_count_except_backup_gpt * sector_size / 1024 / 1024))
|
||||||
|
|
||||||
@ -2560,9 +2571,20 @@ create_part() {
|
|||||||
|
|
||||||
mkfs.fat /dev/$xda*1 #1 efi
|
mkfs.fat /dev/$xda*1 #1 efi
|
||||||
mkfs.ext4 -F $ext4_opts /dev/$xda*2 #2 os + installer
|
mkfs.ext4 -F $ext4_opts /dev/$xda*2 #2 os + installer
|
||||||
|
elif is_xda_gt_2t; then
|
||||||
|
# bios > 2t
|
||||||
|
# 官方安装器是 mkpart BOOT 1M 100M,无论 esp 或者 bios_grub 都用这个分区和大小
|
||||||
|
parted /dev/$xda -s -- \
|
||||||
|
mklabel gpt \
|
||||||
|
mkpart BOOT ext4 1MiB 101MiB \
|
||||||
|
mkpart SYSTEM ext4 101MiB $os_part_end \
|
||||||
|
set 1 bios_grub on
|
||||||
|
update_part
|
||||||
|
|
||||||
|
echo #1 bios_boot
|
||||||
|
mkfs.ext4 -F $ext4_opts /dev/$xda*2 #2 os + installer
|
||||||
else
|
else
|
||||||
# bios
|
# bios
|
||||||
# 官方安装器不支持 bios + >2t
|
|
||||||
parted /dev/$xda -s -- \
|
parted /dev/$xda -s -- \
|
||||||
mklabel msdos \
|
mklabel msdos \
|
||||||
mkpart primary 1MiB 101MiB \
|
mkpart primary 1MiB 101MiB \
|
||||||
@ -3474,10 +3496,8 @@ EOF
|
|||||||
! sh /can_use_cloud_kernel.sh "$xda" $(get_eths); then
|
! sh /can_use_cloud_kernel.sh "$xda" $(get_eths); then
|
||||||
kernel_package=$(echo "$kernel_package" | sed 's/-cloud//')
|
kernel_package=$(echo "$kernel_package" | sed 's/-cloud//')
|
||||||
fi
|
fi
|
||||||
# 如果镜像自带内核跟最佳内核是同一种且有更新
|
|
||||||
# 则 apt install 只会进行更新,不会将包设置成 manual
|
# 该方法包含了 apt-mark manual
|
||||||
# 需要再运行 apt install 才会将包设置成 manual
|
|
||||||
chroot_apt_install $os_dir "$kernel_package"
|
|
||||||
chroot_apt_install $os_dir "$kernel_package"
|
chroot_apt_install $os_dir "$kernel_package"
|
||||||
|
|
||||||
# 使用 autoremove 删除非最佳内核
|
# 使用 autoremove 删除非最佳内核
|
||||||
@ -4178,7 +4198,7 @@ chroot_dnf() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
chroot_apt_update() {
|
chroot_apt_update() {
|
||||||
os_dir=$1
|
local os_dir=$1
|
||||||
|
|
||||||
current_hash=$(cat $os_dir/etc/apt/sources.list $os_dir/etc/apt/sources.list.d/*.sources 2>/dev/null | md5sum)
|
current_hash=$(cat $os_dir/etc/apt/sources.list $os_dir/etc/apt/sources.list.d/*.sources 2>/dev/null | md5sum)
|
||||||
if ! [ "$saved_hash" = "$current_hash" ]; then
|
if ! [ "$saved_hash" = "$current_hash" ]; then
|
||||||
@ -4188,15 +4208,30 @@ chroot_apt_update() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
chroot_apt_install() {
|
chroot_apt_install() {
|
||||||
os_dir=$1
|
local os_dir=$1
|
||||||
shift
|
shift
|
||||||
|
|
||||||
|
# 只安装未安装的软件包
|
||||||
|
# 避免更新浪费时间
|
||||||
|
local pkg='' pkgs=''
|
||||||
|
for pkg in "$@"; do
|
||||||
|
if chroot $os_dir dpkg -s "$pkg" >/dev/null 2>&1; then
|
||||||
|
# 如果已安装则标记为 manual,防止被 autoremove 删除
|
||||||
|
chroot $os_dir apt-mark manual "$pkg"
|
||||||
|
else
|
||||||
|
pkgs="$pkgs $pkg"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# 一次性安装,避免多次 update-initramfs
|
||||||
|
if [ -n "$pkgs" ]; then
|
||||||
chroot_apt_update $os_dir
|
chroot_apt_update $os_dir
|
||||||
DEBIAN_FRONTEND=noninteractive chroot $os_dir apt-get install -y "$@"
|
DEBIAN_FRONTEND=noninteractive chroot $os_dir apt-get install -y $pkgs
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
chroot_apt_remove() {
|
chroot_apt_remove() {
|
||||||
os_dir=$1
|
local os_dir=$1
|
||||||
shift
|
shift
|
||||||
|
|
||||||
# minimal 镜像 删除 grub-pc 时会安装 grub-efi-amd64
|
# minimal 镜像 删除 grub-pc 时会安装 grub-efi-amd64
|
||||||
@ -4219,7 +4254,7 @@ chroot_apt_remove() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
chroot_apt_autoremove() {
|
chroot_apt_autoremove() {
|
||||||
os_dir=$1
|
local os_dir=$1
|
||||||
|
|
||||||
change_confs() {
|
change_confs() {
|
||||||
action=$1
|
action=$1
|
||||||
@ -4310,7 +4345,14 @@ install_fnos() {
|
|||||||
mkdir -p $initrd_dir
|
mkdir -p $initrd_dir
|
||||||
(
|
(
|
||||||
cd $initrd_dir
|
cd $initrd_dir
|
||||||
zcat /iso/install.amd/initrd.gz | cpio -idm
|
suffix=$(
|
||||||
|
case $(uname -m) in
|
||||||
|
x86_64) echo amd ;;
|
||||||
|
aarch64) echo a64 ;;
|
||||||
|
*) ;;
|
||||||
|
esac
|
||||||
|
)
|
||||||
|
zcat /iso/install.$suffix/initrd.gz | cpio -idm
|
||||||
)
|
)
|
||||||
apk del cpio
|
apk del cpio
|
||||||
|
|
||||||
@ -4346,9 +4388,6 @@ install_fnos() {
|
|||||||
# 挂载 proc sys dev
|
# 挂载 proc sys dev
|
||||||
mount_pseudo_fs /os
|
mount_pseudo_fs /os
|
||||||
|
|
||||||
# 更新 initrd
|
|
||||||
# chroot $os_dir update-initramfs -u
|
|
||||||
|
|
||||||
# 更改密码
|
# 更改密码
|
||||||
if is_need_set_ssh_keys; then
|
if is_need_set_ssh_keys; then
|
||||||
set_ssh_keys_and_del_password $os_dir
|
set_ssh_keys_and_del_password $os_dir
|
||||||
@ -4362,6 +4401,31 @@ install_fnos() {
|
|||||||
chroot $os_dir systemctl enable ssh
|
chroot $os_dir systemctl enable ssh
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# fstab
|
||||||
|
{
|
||||||
|
# /
|
||||||
|
uuid=$(lsblk /dev/$xda*2 -no UUID)
|
||||||
|
echo "$fstab_line_os" | sed "s/%s/$uuid/"
|
||||||
|
|
||||||
|
# swapfile
|
||||||
|
# 官方安装器即使 swapfile 设为 0 也会有这行
|
||||||
|
echo "$fstab_line_swapfile"
|
||||||
|
|
||||||
|
# /boot/efi
|
||||||
|
if is_efi; then
|
||||||
|
uuid=$(lsblk /dev/$xda*1 -no UUID)
|
||||||
|
echo "$fstab_line_efi" | sed "s/%s/$uuid/"
|
||||||
|
fi
|
||||||
|
} >$os_dir/etc/fstab
|
||||||
|
|
||||||
|
# 更新 initrd,官方安装器也有这一步
|
||||||
|
# 理论上 /var/tmp 要设置 1777 权限,但飞牛官方安装器安装后不是
|
||||||
|
# 需要先创建 /etc/fstab ,否则会有以下警告
|
||||||
|
# W: Couldn't identify type of root file system for fsck hook
|
||||||
|
mkdir -p $os_dir/var/tmp
|
||||||
|
chmod 1777 $os_dir/var/tmp
|
||||||
|
chroot $os_dir update-initramfs -u
|
||||||
|
|
||||||
# grub
|
# grub
|
||||||
if is_efi; then
|
if is_efi; then
|
||||||
chroot $os_dir grub-install --efi-directory=/boot/efi
|
chroot $os_dir grub-install --efi-directory=/boot/efi
|
||||||
@ -4370,28 +4434,16 @@ install_fnos() {
|
|||||||
chroot $os_dir grub-install /dev/$xda
|
chroot $os_dir grub-install /dev/$xda
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# grub 配置
|
||||||
|
# 取自 strings trim-install | grep GRUB_DISTRIBUTOR
|
||||||
|
sed -i 's/^GRUB_DISTRIBUTOR=.*/GRUB_DISTRIBUTOR="FNOS"/' $os_dir/etc/default/grub
|
||||||
|
|
||||||
# grub tty
|
# grub tty
|
||||||
ttys_cmdline=$(get_ttys console=)
|
ttys_cmdline=$(get_ttys console=)
|
||||||
echo GRUB_CMDLINE_LINUX=\"\$GRUB_CMDLINE_LINUX $ttys_cmdline\" \
|
echo GRUB_CMDLINE_LINUX=\"\$GRUB_CMDLINE_LINUX $ttys_cmdline\" >$os_dir/etc/default/grub.d/tty.cfg
|
||||||
>>$os_dir/etc/default/grub.d/tty.cfg
|
|
||||||
chroot $os_dir update-grub
|
chroot $os_dir update-grub
|
||||||
|
|
||||||
# fstab
|
|
||||||
{
|
|
||||||
# /
|
|
||||||
uuid=$(lsblk /dev/$xda*2 -no UUID)
|
|
||||||
echo "$fstab_line_os" | sed "s/%s/$uuid/"
|
|
||||||
|
|
||||||
# 官方安装器即使 swapfile 设为 0 也会有这行
|
|
||||||
echo "$fstab_line_swapfile" | sed "s/%s/$uuid/"
|
|
||||||
|
|
||||||
# /boot/efi
|
|
||||||
if is_efi; then
|
|
||||||
uuid=$(lsblk /dev/$xda*1 -no UUID)
|
|
||||||
echo "$fstab_line_efi" | sed "s/%s/$uuid/"
|
|
||||||
fi
|
|
||||||
} >$os_dir/etc/fstab
|
|
||||||
|
|
||||||
# 网卡配置
|
# 网卡配置
|
||||||
create_cloud_init_network_config /net.cfg
|
create_cloud_init_network_config /net.cfg
|
||||||
create_network_manager_config /net.cfg $os_dir
|
create_network_manager_config /net.cfg $os_dir
|
||||||
@ -4751,10 +4803,13 @@ EOF
|
|||||||
# 安装最佳内核
|
# 安装最佳内核
|
||||||
flavor=$(get_ubuntu_kernel_flavor)
|
flavor=$(get_ubuntu_kernel_flavor)
|
||||||
echo "Use kernel flavor: $flavor"
|
echo "Use kernel flavor: $flavor"
|
||||||
# 如果镜像自带内核跟最佳内核是同一种且有更新
|
|
||||||
# 则 apt install 只会进行更新,不会将包设置成 manual
|
# 题外话
|
||||||
# 需要再运行 apt install 才会将包设置成 manual
|
# 如果某个包是 auto 状态且有更新
|
||||||
chroot_apt_install $os_dir "linux-image-$flavor"
|
# 则 apt install PKG 只会进行更新,不会将包设置成 manual
|
||||||
|
# 需要再次运行 apt install PKG 才会将包设置成 manual
|
||||||
|
|
||||||
|
# 该方法包含了 apt-mark manual
|
||||||
chroot_apt_install $os_dir "linux-image-$flavor"
|
chroot_apt_install $os_dir "linux-image-$flavor"
|
||||||
|
|
||||||
# 使用 autoremove 删除多余内核
|
# 使用 autoremove 删除多余内核
|
||||||
@ -5556,12 +5611,6 @@ is_list_has() {
|
|||||||
echo "$list" | grep -qFx "$item"
|
echo "$list" | grep -qFx "$item"
|
||||||
}
|
}
|
||||||
|
|
||||||
# hivexget 是 shell 脚本,开头是 #!/bin/bash
|
|
||||||
# 但 alpine 没安装 bash,直接运行 hivexget 会报错
|
|
||||||
hivexget() {
|
|
||||||
ash "$(which hivexget)" "$@"
|
|
||||||
}
|
|
||||||
|
|
||||||
get_windows_type_from_windows_drive() {
|
get_windows_type_from_windows_drive() {
|
||||||
local os_dir=$1
|
local os_dir=$1
|
||||||
|
|
||||||
@ -6015,8 +6064,18 @@ install_windows() {
|
|||||||
echo https://downloadmirror.intel.com/849483/Wired_driver_30.0.1_${arch_intel}.zip
|
echo https://downloadmirror.intel.com/849483/Wired_driver_30.0.1_${arch_intel}.zip
|
||||||
;;
|
;;
|
||||||
x64)
|
x64)
|
||||||
|
id=$(
|
||||||
|
case "$product_ver" in
|
||||||
|
10) echo 18293 ;;
|
||||||
|
11) echo 727998 ;;
|
||||||
|
2016) echo 18737 ;;
|
||||||
|
2019) echo 19372 ;;
|
||||||
|
2022) echo 706171 ;;
|
||||||
|
2025) echo 838943 ;;
|
||||||
|
esac
|
||||||
|
)
|
||||||
# intel 禁止了 wget 下载网页
|
# intel 禁止了 wget 下载网页
|
||||||
wget -U curl/7.54.1 https://www.intel.com/content/www/us/en/download/727998.html -O- |
|
wget -U curl/7.54.1 https://www.intel.com/content/www/us/en/download/$id.html -O- |
|
||||||
grep -Eio -m1 "\"https://.+/(Wired_driver|prowin).*${arch_intel}(legacy)?\.(zip|exe)\"" | tr -d '"' | grep .
|
grep -Eio -m1 "\"https://.+/(Wired_driver|prowin).*${arch_intel}(legacy)?\.(zip|exe)\"" | tr -d '"' | grep .
|
||||||
;;
|
;;
|
||||||
esac ;;
|
esac ;;
|
||||||
@ -6802,7 +6861,7 @@ EOF
|
|||||||
|
|
||||||
# 4kn EFI 分区最少要 260M
|
# 4kn EFI 分区最少要 260M
|
||||||
# https://learn.microsoft.com/windows-hardware/manufacture/desktop/hard-drives-and-partitions
|
# https://learn.microsoft.com/windows-hardware/manufacture/desktop/hard-drives-and-partitions
|
||||||
if is_4kn /dev/$xda; then
|
if is_4kn; then
|
||||||
sed -i 's/is4kn=0/is4kn=1/i' $startnet_cmd
|
sed -i 's/is4kn=0/is4kn=1/i' $startnet_cmd
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user