From 504402e7e566d4222a714a7d469afdc6cc328d88 Mon Sep 17 00:00:00 2001 From: Kroese Date: Sat, 18 Jul 2026 16:52:44 +0200 Subject: [PATCH 01/12] fix: Invalid sed command syntax --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index c534f26..45f4797 100644 --- a/Dockerfile +++ b/Dockerfile @@ -34,7 +34,7 @@ RUN <<'EOF' /run/display.sh sed -i \ - 's|if ! enabled "$GPU" || isAmdCpu || \[\[ "$ARCH" != "amd64" \]\]; then|if ! enabled "$GPU" || [[ "$ARCH" != "amd64" ]]; then|' \ + 's@if ! enabled "$GPU" || isAmdCpu || \[\[ "$ARCH" != "amd64" \]\]; then@if ! enabled "$GPU" || [[ "$ARCH" != "amd64" ]]; then@' \ /run/display.sh sed -i \ From 3e4d337936d8543b232b2c8fa02dde5e9f3a7dd4 Mon Sep 17 00:00:00 2001 From: Kroese Date: Sun, 19 Jul 2026 01:02:24 +0200 Subject: [PATCH 02/12] fix: Decrease default timeout --- src/entry.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/entry.sh b/src/entry.sh index 8865cbd..864427e 100644 --- a/src/entry.sh +++ b/src/entry.sh @@ -6,7 +6,7 @@ set -Eeuo pipefail : "${AUDIO:="N"}" : "${SHUTDOWN:="Y"}" -: "${TIMEOUT:="115"}" +: "${TIMEOUT:="105"}" : "${PLATFORM:="x64"}" : "${BOOT_MODE:="uefi"}" From d4c74574cf5bc8b2f60253591e74df16a78414c3 Mon Sep 17 00:00:00 2001 From: Kroese Date: Sun, 19 Jul 2026 01:44:26 +0200 Subject: [PATCH 03/12] Update Dockerfile --- Dockerfile | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/Dockerfile b/Dockerfile index 45f4797..93ac60b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -26,13 +26,6 @@ COPY --chmod=755 ./src /run/ RUN <<'EOF' set -eu - sed -i \ - -e 's|websocket=$WSS_PORT -vga|websocket=$WSS_PORT${LOSSY_OPT:-} -vga|' \ - -e 's|"-display vnc=:$port -vga $VGA"|"-display vnc=:$port${LOSSY_OPT:-} -vga $VGA"|' \ - -e 's| -vnc :$port,websocket=$WSS_PORT"| -vnc :$port,websocket=$WSS_PORT${LOSSY_OPT:-}"|' \ - -e 's| -vnc :$port"| -vnc :$port${LOSSY_OPT:-}"|' \ - /run/display.sh - sed -i \ 's@if ! enabled "$GPU" || isAmdCpu || \[\[ "$ARCH" != "amd64" \]\]; then@if ! enabled "$GPU" || [[ "$ARCH" != "amd64" ]]; then@' \ /run/display.sh @@ -45,11 +38,6 @@ RUN <<'EOF' 's@USB_OPTS="-device $USB"@& \&\& { [[ "${TABLET:-Y}" =~ ^[Yy] ]] \&\& USB_OPTS+=" -device usb-tablet" || USB_OPTS+=" -device usb-mouse"; }@' \ /run/config.sh - [ "$(grep -c 'LOSSY_OPT' /run/display.sh)" -ge 4 ] || { - echo "patch failed: expected 4 LOSSY_OPT sites in display.sh" >&2 - exit 1 - } - grep -q 'usb-mouse' /run/config.sh || { echo "patch failed: TABLET conditional not injected into config.sh" >&2 exit 1 @@ -59,6 +47,8 @@ RUN <<'EOF' echo "patch failed: AMD GPU gate not removed from display.sh" >&2 exit 1 } + + bash -n /run/display.sh /run/config.sh EOF VOLUME /storage From 71e8de8cd0ca7ed698fc597f4f45a2751bec7cfb Mon Sep 17 00:00:00 2001 From: Kroese Date: Sun, 19 Jul 2026 01:45:06 +0200 Subject: [PATCH 04/12] Update entry.sh --- src/entry.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/src/entry.sh b/src/entry.sh index 864427e..588a23d 100644 --- a/src/entry.sh +++ b/src/entry.sh @@ -5,6 +5,7 @@ set -Eeuo pipefail : "${SUPPORT:="https://github.com/forkymcforkface/chromeos"}" : "${AUDIO:="N"}" +: "${LOSSY:="N"}" : "${SHUTDOWN:="Y"}" : "${TIMEOUT:="105"}" : "${PLATFORM:="x64"}" From 77bb76c846669c1f49e258bf0da4eb48ab47b9e3 Mon Sep 17 00:00:00 2001 From: Kroese Date: Sun, 19 Jul 2026 03:07:40 +0200 Subject: [PATCH 05/12] fix: Add Recreate strategy to Kubernetes deployment --- kubernetes.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kubernetes.yml b/kubernetes.yml index a4dedb4..27f3cc3 100644 --- a/kubernetes.yml +++ b/kubernetes.yml @@ -18,6 +18,8 @@ metadata: name: chromeos spec: replicas: 1 + strategy: + type: Recreate selector: matchLabels: app: chromeos From e0a770e6876fe5702be12a5534f56582d06a2427 Mon Sep 17 00:00:00 2001 From: Kroese Date: Mon, 20 Jul 2026 09:59:59 +0200 Subject: [PATCH 06/12] build: Update QEMU base image to v7.38 --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 93ac60b..c33d330 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,7 @@ # syntax=docker/dockerfile:1 FROM scratch AS runner -COPY --from=qemux/qemu:7.37 / / +COPY --from=qemux/qemu:7.38 / / ARG VERSION_ARG="0.0" ARG DEBCONF_NOWARNINGS="yes" From 8b404ab42a4bbdf8f42a6d5064903eeddbc1d485 Mon Sep 17 00:00:00 2001 From: Kroese Date: Mon, 20 Jul 2026 10:00:47 +0200 Subject: [PATCH 07/12] fix: Prevent races during interactive QEMU shutdown --- src/entry.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/entry.sh b/src/entry.sh index 588a23d..f83ef02 100644 --- a/src/entry.sh +++ b/src/entry.sh @@ -45,7 +45,7 @@ if ! interactive; then "${cmd[@]}" ${ARGS:+ $ARGS} & else startConsole - setsid -w "${cmd[@]}" ${ARGS:+ $ARGS} Date: Tue, 21 Jul 2026 03:08:38 +0200 Subject: [PATCH 08/12] feat: Multi-connection recovery image download --- src/install.sh | 195 +++++++++++++++++++++++++++++-------------------- 1 file changed, 117 insertions(+), 78 deletions(-) diff --git a/src/install.sh b/src/install.sh index dd9c6f9..4ece9e0 100755 --- a/src/install.sh +++ b/src/install.sh @@ -7,6 +7,22 @@ set -Eeuo pipefail VERSION_LC="${VERSION,,}" VERSION_FILTER="" +delay() { + + local i + local seconds="$1" + local msg="Retrying failed download in X seconds..." + + info "${msg/X/$seconds}" + + for i in $(seq "$seconds" -1 1); do + html "${msg/X/$i}" + sleep 1 + done + + return 0 +} + # VERSION can be a channel name (stable/beta/ltc/ltr) or a direct image URL. if [[ "$VERSION_LC" =~ ^https?:// ]]; then url="$VERSION" @@ -30,6 +46,7 @@ fi # A valid ChromeOS GPT layout signals that Flex is already installed. isInstalledDisk() { + local table [ -f "$DATA_IMG" ] && [ -s "$DATA_IMG" ] || return 1 @@ -50,33 +67,45 @@ isInstalledDisk() { if isInstalledDisk; then - # Toggle /syslinux/default.cfg between chromeos-vhd (verified) and chromeos-hd (rw rootfs) via mtools — no mount/loop/SYS_ADMIN needed. + # Toggle /syslinux/default.cfg between chromeos-vhd (verified) and + # chromeos-hd (rw rootfs) via mtools — no mount/loop/SYS_ADMIN needed. if [[ "${DEV_MODE:-}" =~ ^[YyNn] ]]; then set +e - efi_start=$(sfdisk -d "$DATA_IMG" 2>/dev/null | awk -F'[ =,]+' '/EFI-SYSTEM/ {for(i=1;i<=NF;i++) if($i=="start") print $(i+1)}') + efi_start=$(sfdisk -d "$DATA_IMG" 2>/dev/null | + awk -F'[ =,]+' '/EFI-SYSTEM/ {for(i=1;i<=NF;i++) if($i=="start") print $(i+1)}') + if [ -n "$efi_start" ]; then efi_off=$((efi_start * 512)) tmp=$(mktemp) + mtype -i "$DATA_IMG@@$efi_off" ::/syslinux/default.cfg > "$tmp" 2>/dev/null + if [ -s "$tmp" ]; then if [[ "${DEV_MODE:-}" =~ ^[Yy] ]] && grep -q 'chromeos-vhd' "$tmp"; then sed -i 's|chromeos-vhd|chromeos-hd|g' "$tmp" + mcopy -o -i "$DATA_IMG@@$efi_off" "$tmp" ::/syslinux/default.cfg 2>/dev/null && \ info "DEV_MODE=Y: switched boot default to chromeos-hd.A" + elif [[ "${DEV_MODE:-}" =~ ^[Nn] ]] && grep -q 'chromeos-hd' "$tmp"; then sed -i 's|chromeos-hd|chromeos-vhd|g' "$tmp" + mcopy -o -i "$DATA_IMG@@$efi_off" "$tmp" ::/syslinux/default.cfg 2>/dev/null && \ info "DEV_MODE=N: switched boot default to chromeos-vhd.A" fi fi + rm -f "$tmp" fi + set -e fi info "Booting ChromeOS Flex from data disk." + BOOT="none" STORAGE="$FLEX_DIR" + return 0 fi @@ -86,10 +115,12 @@ fi if [ -f "/boot.img" ] && [ -s "/boot.img" ]; then info "Using custom ChromeOS image from /boot.img" + BOOT="/boot.img" STORAGE="$FLEX_DIR" BOOT_MODE="uefi" BOOT_DESC=" ChromeOS Flex (custom)" + return 0 fi @@ -99,9 +130,11 @@ fi if [ -f "$FLEX_DIR/boot.img" ] && [ -s "$FLEX_DIR/boot.img" ]; then info "Reusing existing installer at $FLEX_DIR/boot.img" + BOOT="$FLEX_DIR/boot.img" STORAGE="$FLEX_DIR" BOOT_MODE="uefi" + return 0 fi @@ -109,44 +142,28 @@ zipsize="0" if [ -n "$VERSION_FILTER" ]; then info "Fetching ChromeOS Flex manifest ($VERSION_LC channel)..." - html "Fetching manifest..." - rc=0 - reason="" - log=$(mktemp) manifest="$FLEX_DIR/manifest.json" - rm -f "$manifest" + rm -f -- "$manifest" "$manifest.aria2" - { - LC_ALL=C wget "$MANIFEST_URL" -O "$manifest" --no-verbose --timeout=30 \ - --no-http-keep-alive --output-file="$log" - rc=$? - } || : - - if (( rc != 0 )); then - reason=$(sed -n \ - -e 's/^wget: //p' \ - -e 's/^[0-9-]\{10\} [0-9:]\{8\} ERROR //p' \ - "$log" | tail -n 1) - fi + if ! downloadToFile \ + "$MANIFEST_URL" \ + "$manifest" \ + "Fetching ChromeOS Flex manifest" \ + "0" \ + "1" \ + "N"; then - rm -f "$log" - - if (( rc == 3 )); then - error "Failed to download $MANIFEST_URL because the file could not be written (disk full?)." - exit 60 - elif (( rc != 0 )); then - if [ -n "$reason" ]; then - error "Failed to download $MANIFEST_URL: ${reason%.}." - else - error "Failed to download $MANIFEST_URL with exit status $rc." - fi + rm -f -- "$manifest" "$manifest.aria2" exit 60 fi if [ ! -s "$manifest" ]; then - error "Manifest is empty!" && exit 60 + rm -f -- "$manifest" "$manifest.aria2" + + error "Manifest is empty!" + exit 60 fi url=$(jq -r --arg c "$VERSION_FILTER" ' @@ -179,57 +196,63 @@ fi base="$(basename "${url%%\?*}")" zip_dest="$FLEX_DIR/$base" +connections="${CONNECTIONS:-1}" +msg="Downloading ChromeOS Flex $version" + +info "Downloading $base..." -progress=() -output="" +# Always start without stale partial or aria control files. +rm -f -- "$zip_dest" "$zip_dest.aria2" -# Use Wget's progress bar in a terminal and progress.sh in container logs. -if [ -t 1 ]; then - progress=( --show-progress --progress=bar:noscroll ) -else - output="log" -fi +download_rc=0 -msg="Downloading ChromeOS Flex $version" -html "$msg..." +if downloadToFile \ + "$url" \ + "$zip_dest" \ + "$msg" \ + "${zipsize:-0}" \ + "$connections" \ + "Y"; then -rc=0 -reason="" -log=$(mktemp) + download_rc=0 +else + download_rc=$? +fi -info "Downloading $base..." +if (( download_rc != 0 )); then -rm -f "$zip_dest" -/run/progress.sh "$zip_dest" "${zipsize:-0}" "$msg ([P])..." "$output" & + # Status 2 indicates invalid helper arguments, such as an invalid + # connection count, which cannot be resolved by retrying. + if (( download_rc == 2 )); then + rm -f -- "$zip_dest" "$zip_dest.aria2" + exit 60 + fi -{ - LC_ALL=C wget "$url" -O "$zip_dest" --continue --no-verbose --timeout=30 \ - --no-http-keep-alive "${progress[@]}" \ - --output-file="$log" - rc=$? -} || : + delay 5 -fKill "progress.sh" + # A multi-connection partial file can contain non-sequential ranges and + # cannot safely be resumed by Wget. + if [[ "$connections" =~ ^[1-9][0-9]*$ ]] && (( connections > 1 )); then + if ! rm -f -- "$zip_dest" "$zip_dest.aria2"; then + error "Failed to remove partial download \"$zip_dest\"!" + exit 60 + fi + fi -if (( rc != 0 )); then - reason=$(sed -n \ - -e 's/^wget: //p' \ - -e 's/^[0-9-]\{10\} [0-9:]\{8\} ERROR //p' \ - "$log" | tail -n 1) -fi + info "Retrying $base with a single connection..." -rm -f "$log" + # Retry using single-connection Wget. + if ! downloadToFile \ + "$url" \ + "$zip_dest" \ + "$msg" \ + "${zipsize:-0}" \ + "1" \ + "Y"; then -if (( rc == 3 )); then - error "Failed to download $url because the file could not be written (disk full?)." - exit 60 -elif (( rc != 0 )); then - if [ -n "$reason" ]; then - error "Failed to download $url: ${reason%.}." - else - error "Failed to download $url with exit status $rc." + rm -f -- "$zip_dest" "$zip_dest.aria2" + exit 60 fi - exit 60 fi if [ ! -s "$zip_dest" ]; then @@ -237,13 +260,14 @@ if [ ! -s "$zip_dest" ]; then exit 60 fi -# Catch silent truncation: a valid Flex recovery zip is always >1GB; <100MB means CDN error page or partial download. -if ! actual_size=$(stat -c%s "$zip_dest"); then +# Catch silent truncation: a valid Flex recovery ZIP is always larger than +# 1 GB; anything below 100 MB is likely an error page or partial download. +if ! actual_size=$(stat -c%s -- "$zip_dest"); then error "Failed to determine downloaded file size: $zip_dest" exit 60 fi -if [ "$actual_size" -lt 100000000 ]; then +if (( actual_size < 100000000 )); then error "Downloaded file is suspiciously small ($actual_size bytes)" exit 60 fi @@ -254,36 +278,50 @@ info "Extracting $base..." html "Extracting image..." tmp="$FLEX_DIR/extract" + rm -rf "$tmp" mkdir -p "$tmp" extract_size=$(7z l -slt "$zip_dest" 2>/dev/null | awk -F' = ' '/^Size = [0-9]+$/ && $2 > max { max = $2 } END { print max + 0 }') -/run/progress.sh "$tmp" "${extract_size:-0}" "Extracting image ([P])..." & +/run/progress.sh \ + "$tmp" \ + "${extract_size:-0}" \ + "Extracting image ([P])..." & rc=0 -{ 7z x -y "$zip_dest" -o"$tmp" > /dev/null; rc=$?; } || : + +{ + 7z x -y "$zip_dest" -o"$tmp" > /dev/null + rc=$? +} || : fKill "progress.sh" if (( rc != 0 )); then rm -rf "$tmp" - error "Failed to extract $base" && exit 32 + + error "Failed to extract $base" + exit 32 fi img=$(find "$tmp" -type f -iname "*.bin" -print -quit) if [ ! -s "$img" ]; then rm -rf "$tmp" - error "Could not find ChromeOS Flex image in archive" && exit 32 + + error "Could not find ChromeOS Flex image in archive" + exit 32 fi mv "$img" "$FLEX_DIR/boot.img" + rm -rf "$tmp" rm -f "$zip_dest" -setOwner "$FLEX_DIR/boot.img" || warn "failed to set owner on installer image" +setOwner "$FLEX_DIR/boot.img" || + warn "failed to set owner on installer image" BOOT_MODE="uefi" BOOT="$FLEX_DIR/boot.img" @@ -291,4 +329,5 @@ STORAGE="$FLEX_DIR" BOOT_DESC=" ChromeOS Flex $version" info "ChromeOS Flex installer ready at $BOOT" + return 0 From 6723a7040eb84860e4e08595487e35469aff3cb0 Mon Sep 17 00:00:00 2001 From: Kroese Date: Tue, 21 Jul 2026 03:19:54 +0200 Subject: [PATCH 09/12] fix: Use delay function from base image --- src/install.sh | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/install.sh b/src/install.sh index 4ece9e0..0b62cbf 100755 --- a/src/install.sh +++ b/src/install.sh @@ -7,22 +7,6 @@ set -Eeuo pipefail VERSION_LC="${VERSION,,}" VERSION_FILTER="" -delay() { - - local i - local seconds="$1" - local msg="Retrying failed download in X seconds..." - - info "${msg/X/$seconds}" - - for i in $(seq "$seconds" -1 1); do - html "${msg/X/$i}" - sleep 1 - done - - return 0 -} - # VERSION can be a channel name (stable/beta/ltc/ltr) or a direct image URL. if [[ "$VERSION_LC" =~ ^https?:// ]]; then url="$VERSION" From 6af102909ce68ae5598fe23a3a4b9d9462602098 Mon Sep 17 00:00:00 2001 From: Kroese Date: Tue, 21 Jul 2026 05:22:11 +0200 Subject: [PATCH 10/12] feat: Use retry function from base image --- src/install.sh | 160 +++++++++++++++++++++++++++---------------------- 1 file changed, 87 insertions(+), 73 deletions(-) diff --git a/src/install.sh b/src/install.sh index 0b62cbf..abbd808 100755 --- a/src/install.sh +++ b/src/install.sh @@ -122,6 +122,89 @@ if [ -f "$FLEX_DIR/boot.img" ] && [ -s "$FLEX_DIR/boot.img" ]; then return 0 fi +downloadFile() { + + local url="$1" + local dest="$2" + local message="$3" + local expected="${4:-0}" + local connections="${5:-1}" + local total size + + if downloadToFile \ + "$url" \ + "$dest" \ + "$message" \ + "$expected" \ + "$connections" \ + "Y"; then + return 0 + fi + + local rc=$? + (( rc != 0 )) && return "$rc" + + if [ ! -s "$dest" ]; then + + error "Failed to download $url: the downloaded file is empty." + + if ! rm -f -- "$dest" "$dest.aria2"; then + warn "failed to remove invalid download \"$dest\"!" + fi + + return 1 + fi + + if ! total=$(stat -c%s -- "$dest"); then + error "Failed to determine downloaded file size: $dest" + return 1 + fi + + size=$(formatBytes "$total") || size="$total bytes" + + # Catch silent truncation: a valid Flex recovery ZIP is always larger than + # 1 GB; anything below 100 MB is likely an error page or partial download. + if (( total < 100000000 )); then + + error "Downloaded file is suspiciously small: $size" + + if ! rm -f -- "$dest" "$dest.aria2"; then + warn "failed to remove invalid download \"$dest\"!" + fi + + return 1 + fi + + return 0 +} + +downloadImage() { + + local url="$1" + local dest="$2" + local base="$3" + local version="$4" + local expected="${5:-0}" + local connections="${CONNECTIONS:-1}" + local msg="Downloading ChromeOS Flex $version" + + info "Downloading $base..." + + if ! downloadRetry \ + "$dest" \ + "$connections" \ + "5" \ + "$base" \ + "$url" \ + "$dest" \ + "$msg" \ + "$expected"; then + return 1 + fi + + return 0 +} + zipsize="0" if [ -n "$VERSION_FILTER" ]; then @@ -145,7 +228,6 @@ if [ -n "$VERSION_FILTER" ]; then if [ ! -s "$manifest" ]; then rm -f -- "$manifest" "$manifest.aria2" - error "Manifest is empty!" exit 60 fi @@ -180,84 +262,16 @@ fi base="$(basename "${url%%\?*}")" zip_dest="$FLEX_DIR/$base" -connections="${CONNECTIONS:-1}" -msg="Downloading ChromeOS Flex $version" - -info "Downloading $base..." - -# Always start without stale partial or aria control files. -rm -f -- "$zip_dest" "$zip_dest.aria2" -download_rc=0 - -if downloadToFile \ +if ! downloadImage \ "$url" \ "$zip_dest" \ - "$msg" \ - "${zipsize:-0}" \ - "$connections" \ - "Y"; then - - download_rc=0 -else - download_rc=$? -fi - -if (( download_rc != 0 )); then - - # Status 2 indicates invalid helper arguments, such as an invalid - # connection count, which cannot be resolved by retrying. - if (( download_rc == 2 )); then - rm -f -- "$zip_dest" "$zip_dest.aria2" - exit 60 - fi - - delay 5 - - # A multi-connection partial file can contain non-sequential ranges and - # cannot safely be resumed by Wget. - if [[ "$connections" =~ ^[1-9][0-9]*$ ]] && (( connections > 1 )); then - if ! rm -f -- "$zip_dest" "$zip_dest.aria2"; then - error "Failed to remove partial download \"$zip_dest\"!" - exit 60 - fi - fi - - info "Retrying $base with a single connection..." - - # Retry using single-connection Wget. - if ! downloadToFile \ - "$url" \ - "$zip_dest" \ - "$msg" \ - "${zipsize:-0}" \ - "1" \ - "Y"; then - - rm -f -- "$zip_dest" "$zip_dest.aria2" - exit 60 - fi -fi - -if [ ! -s "$zip_dest" ]; then - error "Failed to download $url: the downloaded file is empty." - exit 60 -fi - -# Catch silent truncation: a valid Flex recovery ZIP is always larger than -# 1 GB; anything below 100 MB is likely an error page or partial download. -if ! actual_size=$(stat -c%s -- "$zip_dest"); then - error "Failed to determine downloaded file size: $zip_dest" + "$base" \ + "$version" \ + "${zipsize:-0}"; then exit 60 fi -if (( actual_size < 100000000 )); then - error "Downloaded file is suspiciously small ($actual_size bytes)" - exit 60 -fi - -html "Download finished successfully..." - info "Extracting $base..." html "Extracting image..." From 01f0862116ba4d5c68f4187de4c9b3f4395b01c4 Mon Sep 17 00:00:00 2001 From: Kroese Date: Tue, 21 Jul 2026 06:06:34 +0200 Subject: [PATCH 11/12] feat: Improve download function --- src/install.sh | 74 ++++++++++++-------------------------------------- 1 file changed, 17 insertions(+), 57 deletions(-) diff --git a/src/install.sh b/src/install.sh index abbd808..37fa381 100755 --- a/src/install.sh +++ b/src/install.sh @@ -129,53 +129,14 @@ downloadFile() { local message="$3" local expected="${4:-0}" local connections="${5:-1}" - local total size - - if downloadToFile \ - "$url" \ - "$dest" \ - "$message" \ - "$expected" \ - "$connections" \ - "Y"; then - return 0 - fi - - local rc=$? - (( rc != 0 )) && return "$rc" - - if [ ! -s "$dest" ]; then - - error "Failed to download $url: the downloaded file is empty." - - if ! rm -f -- "$dest" "$dest.aria2"; then - warn "failed to remove invalid download \"$dest\"!" - fi - - return 1 - fi - - if ! total=$(stat -c%s -- "$dest"); then - error "Failed to determine downloaded file size: $dest" - return 1 - fi - - size=$(formatBytes "$total") || size="$total bytes" - # Catch silent truncation: a valid Flex recovery ZIP is always larger than - # 1 GB; anything below 100 MB is likely an error page or partial download. - if (( total < 100000000 )); then - - error "Downloaded file is suspiciously small: $size" - - if ! rm -f -- "$dest" "$dest.aria2"; then - warn "failed to remove invalid download \"$dest\"!" - fi - - return 1 - fi - - return 0 + downloadToFile \ + "$url" \ + "$dest" \ + "$message" \ + "$expected" \ + "$connections" \ + "Y" } downloadImage() { @@ -190,17 +151,16 @@ downloadImage() { info "Downloading $base..." - if ! downloadRetry \ - "$dest" \ - "$connections" \ - "5" \ - "$base" \ - "$url" \ - "$dest" \ - "$msg" \ - "$expected"; then - return 1 - fi + downloadRetry \ + "$dest" \ + "$connections" \ + "5" \ + "$base" \ + "100000000" \ + "$url" \ + "$dest" \ + "$msg" \ + "$expected" || return $? return 0 } From caa4b82faf53241bfb3db440a968780f738e5738 Mon Sep 17 00:00:00 2001 From: Kroese Date: Thu, 23 Jul 2026 19:55:16 +0200 Subject: [PATCH 12/12] build: Update QEMU base image to v7.39 --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index c33d330..65eca13 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,7 @@ # syntax=docker/dockerfile:1 FROM scratch AS runner -COPY --from=qemux/qemu:7.38 / / +COPY --from=qemux/qemu:7.39 / / ARG VERSION_ARG="0.0" ARG DEBCONF_NOWARNINGS="yes"