windows: 支持磁力链接下载 iso

fixes #268
This commit is contained in:
bin456789
2025-02-21 00:30:33 +08:00
parent 8e8bf610dc
commit 6263f994af
2 changed files with 173 additions and 65 deletions

View File

@@ -1358,50 +1358,55 @@ Continue?
# 注意 windows server 2008 r2 serverdatacenter 不用改
image_name=${image_name/windows server 2008 server/windows longhorn server}
iso_filetype='iso raw'
iso_tested=false
if [[ "$iso" = magnet:* ]]; then
: # 不测试磁力链接
else
iso_filetype='iso raw'
iso_tested=false
# 获取 massgrave.dev 直链
if grep -Eiq '\.massgrave\.dev/.*\.(iso|img)' <<<"$iso"; then
# 如果已经是 iso 直链则跳过下面的 iso 测试
if test_url_grace "$iso" "$iso_filetype"; then
iso_tested=true
# 获取 massgrave.dev 直链
if grep -Eiq '\.massgrave\.dev/.*\.(iso|img)' <<<"$iso"; then
# 如果已经是 iso 直链则跳过下面的 iso 测试
if test_url_grace "$iso" "$iso_filetype"; then
iso_tested=true
else
msg="Could not find direct link for $iso"
if ! iso=$(grep -oE 'https?.*\.iso[^"]*' $tmp/img-test | sed 's/&amp;/\&/g' | grep .); then
error_and_exit "$msg"
fi
fi
fi
# 测试是否是 iso
if ! $iso_tested; then
test_url "$iso" "$iso_filetype"
fi
# 判断 iso 架构是否兼容
# https://gitlab.com/libosinfo/osinfo-db/-/tree/main/data/os/microsoft.com?ref_type=heads
# uupdump linux 下合成的标签是 ARM64windows下合成的标签是 A64
if file -b "$tmp/img-test" | grep -Eq '_(A64|ARM64)'; then
iso_arch=arm64
else
msg="Could not find direct link for $iso"
if ! iso=$(grep -oE 'https?.*\.iso[^"]*' $tmp/img-test | sed 's/&amp;/\&/g' | grep .); then
error_and_exit "$msg"
iso_arch=x86_or_x64
fi
if ! {
{ [ "$basearch" = x86_64 ] && [ "$iso_arch" = x86_or_x64 ]; } ||
{ [ "$basearch" = aarch64 ] && [ "$iso_arch" = arm64 ]; }
}; then
warn "
The current machine is $basearch, but it seems the ISO is for $iso_arch. Continue?
当前机器是 $basearch,但 ISO 似乎是 $iso_arch。继续安装?"
read -r -p '[y/N]: '
if ! [[ "$REPLY" = [Yy] ]]; then
exit
fi
fi
fi
# 测试是否是 iso
if ! $iso_tested; then
test_url "$iso" "$iso_filetype"
fi
[ -n "$boot_wim" ] && test_url "$boot_wim" 'wim'
# 判断 iso 架构是否兼容
# https://gitlab.com/libosinfo/osinfo-db/-/tree/main/data/os/microsoft.com?ref_type=heads
if file -b "$tmp/img-test" | grep -q '_A64'; then
iso_arch=arm64
else
iso_arch=x86_or_x64
fi
if ! {
{ [ "$basearch" = x86_64 ] && [ "$iso_arch" = x86_or_x64 ]; } ||
{ [ "$basearch" = aarch64 ] && [ "$iso_arch" = arm64 ]; }
}; then
warn "
The current machine is $basearch, but it seems the ISO is for $iso_arch. Continue?
当前机器是 $basearch,但 ISO 似乎是 $iso_arch。继续安装?"
read -r -p '[y/N]: '
if ! [[ "$REPLY" = [Yy] ]]; then
exit
fi
fi
eval "${step}_iso='$iso'"
eval "${step}_boot_wim='$boot_wim'"
eval "${step}_image_name='$image_name'"

161
trans.sh
View File

@@ -84,12 +84,13 @@ wget() {
}
is_have_cmd() {
command -v "$1" >/dev/null
# command -v 包括脚本里面的方法
is_have_cmd_on_disk / "$1"
}
is_have_cmd_on_disk() {
os_dir=$1
cmd=$2
local os_dir=$1
local cmd=$2
for bin_dir in /bin /sbin /usr/bin /usr/sbin; do
if [ -f "$os_dir$bin_dir/$cmd" ]; then
@@ -127,6 +128,18 @@ retry() {
done
}
get_url_type() {
if [[ "$1" = magnet:* ]]; then
echo bt
else
echo http
fi
}
is_magnet_link() {
[[ "$1" = magnet:* ]]
}
download() {
url=$1
path=$2
@@ -138,26 +151,17 @@ download() {
# https://aria2.github.io/manual/en/html/aria2c.html#cmdoption-o
# 构造 aria2 参数
# 没有指定文件名的情况
if [ -z "$path" ]; then
save=""
else
# 文件名是绝对路径
if [[ "$path" = '/*' ]]; then
save="-d / -o $path"
else
# 文件名是相对路径
save="-o $path"
fi
save=
# 文件夹
if [[ "$path" = '/*' ]]; then
save="$save -d /"
fi
if ! is_have_cmd aria2c; then
apk add aria2
fi
# stdbuf 在 coreutils 包里面
if ! is_have_cmd stdbuf; then
apk add coreutils
# 文件名
if [ -n "$path" ]; then
case "$(get_url_type "$url")" in
http) save="$save -o $path" ;;
bt) save="$save -O 1=$path" ;;
esac
fi
# 阿里云源限速,而且检测 user-agent 禁止 axel/aria2 下载
@@ -175,13 +179,18 @@ download() {
# fi
# --user-agent=Wget/1.21.1 \
# --retry-wait 5
echo "$url"
retry 5 5 stdbuf -oL -eL aria2c -x4 \
--allow-overwrite=true \
--summary-interval=0 \
--max-tries 1 \
$save "$url"
# 检测大小时已经下载了种子
if [ "$(get_url_type "$url")" = bt ]; then
torrent="$(get_torrent_path_by_magnet $url)"
if ! [ -f "$torrent" ]; then
download_torrent_by_magnet "$url" "$torrent"
fi
url=$torrent
fi
aria2c $save "$url"
}
update_part() {
@@ -1037,6 +1046,10 @@ EOF
done
}
newline_to_comma() {
tr '\n' ','
}
space_to_newline() {
sed 's/ /\n/g'
}
@@ -1990,6 +2003,96 @@ get_http_file_size() {
tail -1 | awk '{print $2}' | grep .
}
get_url_hash() {
url=$1
echo "$url" | md5sum | awk '{print $1}'
}
aria2c() {
if ! is_have_cmd aria2c; then
apk add aria2
fi
# stdbuf 在 coreutils 包里面
if ! is_have_cmd stdbuf; then
apk add coreutils
fi
# 指定 bt 种子时没有链接,因此忽略错误
echo "$@" | grep -o '(http|https|magnet):[^ ]*' || true
# 下载 tracker
# 在 sub shell 里面无法保存变量,因此写入到文件
if echo "$@" | grep -Eq 'magnet:|\.torrent' && ! [ -f "/tmp/trackers" ]; then
# 独自一行下载,不然下载失败不会报错
# 里面有空行
# txt=$(wget -O- https://raw.githubusercontent.com/ngosang/trackerslist/master/trackers_best.txt | grep .)
# txt=$(wget -O- https://raw.githubusercontent.com/ngosang/trackerslist/master/trackers_all.txt | grep .)
txt=$(wget -O- https://cf.trackerslist.com/best.txt | grep .)
# sed 删除最后一个逗号
echo "$txt" | newline_to_comma | sed 's/,$//' >/tmp/trackers
fi
# --dht-entry-point=router.bittorrent.com:6881 \
# --dht-entry-point=dht.transmissionbt.com:6881 \
# --dht-entry-point=router.utorrent.com:6881 \
retry 5 5 stdbuf -oL -eL aria2c \
-x4 \
--seed-time=0 \
--allow-overwrite=true \
--summary-interval=0 \
--max-tries 1 \
--bt-tracker="$([ -f "/tmp/trackers" ] && cat /tmp/trackers)" \
"$@"
}
download_torrent_by_magnet() {
url=$1
dst=$2
url_hash=$(get_url_hash "$url")
mkdir -p /tmp/bt/$url_hash
# 不支持 -o bt.torrent 指定文件名
aria2c "$url" \
--bt-metadata-only=true \
--bt-save-metadata=true \
-d /tmp/bt/$url_hash
mv /tmp/bt/$url_hash/*.torrent "$dst"
rm -rf /tmp/bt/$url_hash
}
get_torrent_path_by_magnet() {
echo "/tmp/bt/$(get_url_hash "$1").torrent"
}
get_bt_file_size() {
url=$1
torrent="$(get_torrent_path_by_magnet $url)"
download_torrent_by_magnet "$url" "$torrent" >&2
# 列出第一个文件的大小
# idx|path/length
# ===+===========================================================================
# 1|./zh-cn_windows_11_consumer_editions_version_24h2_updated_jan_2025_x64_dvd_7a8e5a29.iso
# |6.1GiB (6,557,558,784)
aria2c --show-files=true "$torrent" |
grep -F -A1 ' 1|./' | tail -1 | grep -o '(.*)' | sed -E 's/[(),]//g' | grep .
}
get_link_file_size() {
if is_magnet_link "$1" >&2; then
get_bt_file_size "$1"
else
get_http_file_size "$1"
fi
}
pipe_extract() {
# alpine busybox 自带 gzip但官方版也许性能更好
case "$img_type_warp" in
@@ -2073,7 +2176,7 @@ create_part() {
# xda*1 星号用于 nvme0n1p1 的字母 p
# shellcheck disable=SC2154
if [ "$distro" = windows ]; then
if ! size_bytes=$(get_http_file_size "$iso"); then
if ! size_bytes=$(get_link_file_size "$iso"); then
# 默认值最大的iso 23h2 假设 7g
size_bytes=$((7 * 1024 * 1024 * 1024))
fi