From 7c051fb64891f72ce030896a3ac14375031c98b4 Mon Sep 17 00:00:00 2001 From: "CanbiZ (MickLesk)" <47820557+MickLesk@users.noreply.github.com> Date: Wed, 11 Mar 2026 14:23:56 +0100 Subject: [PATCH] Improve arm64 support and arch-specific downloads Add clearer architecture error messages and gate arm64 usage, plus implement architecture-aware behavior across the toolkit. Changes include: update exit-code messages to reference amd64/arm64, refuse arm64 unless explicitly enabled, show architecture in summaries, and use arch-specific package lists when installing in containers. Make downloads for FFmpeg and yq choose the correct amd64/arm64 binaries, tighten template download error handling and formatting, and clean up minor whitespace/comment issues. These changes aim to make arm64 handling explicit and downloads/installations more robust for non-amd64 systems. --- misc/api.func | 10 +-- misc/build.func | 153 +++++++++++++++++++++------------------- misc/core.func | 5 ++ misc/error_handler.func | 2 +- misc/install.func | 1 - misc/tools.func | 21 +++++- 6 files changed, 110 insertions(+), 82 deletions(-) diff --git a/misc/api.func b/misc/api.func index e29975e2c..7815d4a33 100644 --- a/misc/api.func +++ b/misc/api.func @@ -196,7 +196,7 @@ explain_exit_code() { 103) echo "Validation: Shell is not Bash" ;; 104) echo "Validation: Not running as root (or invoked via sudo)" ;; 105) echo "Validation: Proxmox VE version not supported" ;; - 106) echo "Validation: Architecture not supported (ARM / PiMox)" ;; + 106) echo "Validation: Unsupported architecture (requires amd64 or arm64)" ;; 107) echo "Validation: Kernel key parameters unreadable" ;; 108) echo "Validation: Kernel key limits exceeded" ;; 109) echo "Proxmox: No available container ID after max attempts" ;; @@ -348,10 +348,10 @@ explain_exit_code() { json_escape() { # Escape a string for safe JSON embedding using awk (handles any input size). # Pipeline: strip ANSI → remove control chars → escape \ " TAB → join lines with \n - printf '%s' "$1" \ - | sed 's/\x1b\[[0-9;]*[a-zA-Z]//g' \ - | tr -d '\000-\010\013\014\016-\037\177\r' \ - | awk ' + printf '%s' "$1" | + sed 's/\x1b\[[0-9;]*[a-zA-Z]//g' | + tr -d '\000-\010\013\014\016-\037\177\r' | + awk ' BEGIN { ORS = "" } { gsub(/\\/, "\\\\") # backslash → \\ diff --git a/misc/build.func b/misc/build.func index 1bf45a69f..5ce216cd9 100644 --- a/misc/build.func +++ b/misc/build.func @@ -1826,9 +1826,9 @@ advanced_settings() { while [ $STEP -le $MAX_STEP ]; do case $STEP in - # ═══════════════════════════════════════════════════════════════════════════ + # ------------------------------------------------------------------------------ # STEP 1: Container Type - # ═══════════════════════════════════════════════════════════════════════════ + # ------------------------------------------------------------------------------ 1) local default_on="ON" local default_off="OFF" @@ -1851,9 +1851,9 @@ advanced_settings() { fi ;; - # ═══════════════════════════════════════════════════════════════════════════ + # ------------------------------------------------------------------------------ # STEP 2: Root Password - # ════════════════════════════════════════════════════════════════════════���══ + # ------------------------------------------------------------------------------ 2) if PW1=$(whiptail --backtitle "Proxmox VE Helper Scripts [Step $STEP/$MAX_STEP]" \ --title "ROOT PASSWORD" \ @@ -1905,9 +1905,9 @@ advanced_settings() { fi ;; - # ═══════════════════════════════════════════════════════════════════════════ + # ------------------------------------------------------------------------------ # STEP 3: Container ID - # ═══════════════════════════════════════════════════════════════════════════ + # ------------------------------------------------------------------------------ 3) if result=$(whiptail --backtitle "Proxmox VE Helper Scripts [Step $STEP/$MAX_STEP]" \ --title "CONTAINER ID" \ @@ -1939,9 +1939,9 @@ advanced_settings() { fi ;; - # ═══════════════════════════════════════════════════════════════════════════ + # ------------------------------------------------------------------------------ # STEP 4: Hostname - # ═══════════════════════════════════════════════════════════════════════════ + # ------------------------------------------------------------------------------ 4) if result=$(whiptail --backtitle "Proxmox VE Helper Scripts [Step $STEP/$MAX_STEP]" \ --title "HOSTNAME" \ @@ -1962,9 +1962,9 @@ advanced_settings() { fi ;; - # ═══════════════════════════════════════════════════════════════════════════ + # ------------------------------------------------------------------------------ # STEP 5: Disk Size - # ═══════════════════════════════════════════════════════════════════════════ + # ------------------------------------------------------------------------------ 5) if result=$(whiptail --backtitle "Proxmox VE Helper Scripts [Step $STEP/$MAX_STEP]" \ --title "DISK SIZE" \ @@ -1983,9 +1983,9 @@ advanced_settings() { fi ;; - # ═══════════════════════════════════════════════════════════════════════════ + # ------------------------------------------------------------------------------ # STEP 6: CPU Cores - # ═══════════════════════════════════════════════════════════════════════════ + # ------------------------------------------------------------------------------ 6) if result=$(whiptail --backtitle "Proxmox VE Helper Scripts [Step $STEP/$MAX_STEP]" \ --title "CPU CORES" \ @@ -2004,9 +2004,9 @@ advanced_settings() { fi ;; - # ═══════════════════════════════════════════════════════════════════════════ + # ------------------------------------------------------------------------------ # STEP 7: RAM Size - # ═══════════════════════════════════════════════════════════════════════════ + # ------------------------------------------------------------------------------ 7) if result=$(whiptail --backtitle "Proxmox VE Helper Scripts [Step $STEP/$MAX_STEP]" \ --title "RAM SIZE" \ @@ -2025,9 +2025,9 @@ advanced_settings() { fi ;; - # ═══════════════════════════════════════════════════════════════════════════ + # ------------------------------------------------------------------------------ # STEP 8: Network Bridge - # ═══════════════════════════════════════════════════════════════════════════ + # ------------------------------------------------------------------------------ 8) if [[ ${#BRIDGE_MENU_OPTIONS[@]} -eq 0 ]]; then # Validate default bridge exists @@ -2063,9 +2063,9 @@ advanced_settings() { fi ;; - # ═══════════════════════════════════════════════════════════════════════════ + # ------------------------------------------------------------------------------ # STEP 9: IPv4 Configuration - # ═══════════════════════════════════════════════════════════════════════════ + # ------------------------------------------------------------------------------ 9) if result=$(whiptail --backtitle "Proxmox VE Helper Scripts [Step $STEP/$MAX_STEP]" \ --title "IPv4 CONFIGURATION" \ @@ -2160,9 +2160,9 @@ advanced_settings() { fi ;; - # ═══════════════════════════════════════════════════════════════════════════ + # ------------------------------------------------------------------------------ # STEP 10: IPv6 Configuration - # ═══════════════════════════════════════════════════════════════════════════ + # ------------------------------------------------------------------------------ 10) if result=$(whiptail --backtitle "Proxmox VE Helper Scripts [Step $STEP/$MAX_STEP]" \ --title "IPv6 CONFIGURATION" \ @@ -2235,9 +2235,9 @@ advanced_settings() { fi ;; - # ═══════════════════════════════════════════════════════════════════════════ + # ------------------------------------------------------------------------------ # STEP 11: MTU Size - # ═══════════════════════════════════════════════════════════════════════════ + # ------------------------------------------------------------------------------ 11) if result=$(whiptail --backtitle "Proxmox VE Helper Scripts [Step $STEP/$MAX_STEP]" \ --title "MTU SIZE" \ @@ -2255,9 +2255,9 @@ advanced_settings() { fi ;; - # ═══════════════════════════════════════════════════════════════════════════ + # ------------------------------------------------------------------------------ # STEP 12: DNS Search Domain - # ═══════════════════════════════════════════════════════════════════════════ + # ------------------------------------------------------------------------------ 12) if result=$(whiptail --backtitle "Proxmox VE Helper Scripts [Step $STEP/$MAX_STEP]" \ --title "DNS SEARCH DOMAIN" \ @@ -2271,9 +2271,9 @@ advanced_settings() { fi ;; - # ═══════════════════════════════════════════════════════════════════════════ + # ------------------------------------------------------------------------------ # STEP 13: DNS Server - # ═══════════════════════════════════════════════════════════════════════════ + # ------------------------------------------------------------------------------ 13) if result=$(whiptail --backtitle "Proxmox VE Helper Scripts [Step $STEP/$MAX_STEP]" \ --title "DNS SERVER" \ @@ -2287,9 +2287,9 @@ advanced_settings() { fi ;; - # ═══════════════════════════════════════════════════════════════════════════ + # ------------------------------------------------------------------------------ # STEP 14: MAC Address - # ═══════════════════════════════════════════════════════════════════════════ + # ------------------------------------------------------------------------------ 14) if result=$(whiptail --backtitle "Proxmox VE Helper Scripts [Step $STEP/$MAX_STEP]" \ --title "MAC ADDRESS" \ @@ -2307,9 +2307,9 @@ advanced_settings() { fi ;; - # ═══════════════════════════════════════════════════════════════════════════ + # ------------------------------------------------------------------------------ # STEP 15: VLAN Tag - # ═══════════════════════════════════════════════════════════════════════════ + # ------------------------------------------------------------------------------ 15) if result=$(whiptail --backtitle "Proxmox VE Helper Scripts [Step $STEP/$MAX_STEP]" \ --title "VLAN TAG" \ @@ -2327,9 +2327,9 @@ advanced_settings() { fi ;; - # ═══════════════════════════════════════════════════════════════════════════ + # ------------------------------------------------------------------------------ # STEP 16: Tags - # ═══════════════════════════════════════════════════════════════════════════ + # ------------------------------------------------------------------------------ 16) if result=$(whiptail --backtitle "Proxmox VE Helper Scripts [Step $STEP/$MAX_STEP]" \ --title "CONTAINER TAGS" \ @@ -2349,18 +2349,18 @@ advanced_settings() { fi ;; - # ═══════════════════════════════════════════════════════════════════════════ + # ------------------------------------------------------------------------------ # STEP 17: SSH Settings - # ═══════════════════════════════════════════════════════════════════════════ + # ------------------------------------------------------------------------------ 17) configure_ssh_settings "Step $STEP/$MAX_STEP" # configure_ssh_settings handles its own flow, always advance ((STEP++)) ;; - # ═══════════════════════════════════════════════════════════════════════════ + # ------------------------------------------------------------------------------ # STEP 18: FUSE Support - # ═══════════════════════════════════════════════════════════════════════════ + # ------------------------------------------------------------------------------ 18) local fuse_default_flag="--defaultno" [[ "$_enable_fuse" == "yes" || "$_enable_fuse" == "1" ]] && fuse_default_flag="" @@ -2382,9 +2382,9 @@ advanced_settings() { ((STEP++)) ;; - # ═══════════════════════════════════════════════════════════════════════════ + # ------------------------------------------------------------------------------ # STEP 19: TUN/TAP Support - # ═══════════════════════════════════════════════════════════════════════════ + # ------------------------------------------------------------------------------ 19) local tun_default_flag="--defaultno" [[ "$_enable_tun" == "yes" || "$_enable_tun" == "1" ]] && tun_default_flag="" @@ -2406,9 +2406,9 @@ advanced_settings() { ((STEP++)) ;; - # ═══════════════════════════════════════════════════════════════════════════ + # ------------------------------------------------------------------------------ # STEP 20: Nesting Support - # ═══════════════════════════════════════════════════════════════════════════ + # ------------------------------------------------------------------------------ 20) local nesting_default_flag="" [[ "$_enable_nesting" == "0" || "$_enable_nesting" == "no" ]] && nesting_default_flag="--defaultno" @@ -2436,9 +2436,9 @@ advanced_settings() { ((STEP++)) ;; - # ═══════════════════════════════════════════════════════════════════════════ + # ------------------------------------------------------------------------------ # STEP 21: GPU Passthrough - # ═══════════════════════════════════════════════════════════════════════════ + # ------------------------------------------------------------------------------ 21) local gpu_default_flag="--defaultno" [[ "$_enable_gpu" == "yes" ]] && gpu_default_flag="" @@ -2460,9 +2460,9 @@ advanced_settings() { ((STEP++)) ;; - # ═══════════════════════════════════════════════════════════════════════════ + # ------------------------------------------------------------------------------ # STEP 22: Keyctl Support (Docker/systemd) - # ═══════════════════════════════════════════════════════════════════════════ + # ------------------------------------------------------------------------------ 22) local keyctl_default_flag="--defaultno" [[ "$_enable_keyctl" == "1" ]] && keyctl_default_flag="" @@ -2484,9 +2484,9 @@ advanced_settings() { ((STEP++)) ;; - # ═══════════════════════════════════════════════════════════════════════════ + # ------------------------------------------------------------------------------ # STEP 23: APT Cacher Proxy - # ═══════════════════════════════════════════════════════════════════════════ + # ------------------------------------------------------------------------------ 23) local apt_cacher_default_flag="--defaultno" [[ "$_apt_cacher" == "yes" ]] && apt_cacher_default_flag="" @@ -2516,9 +2516,9 @@ advanced_settings() { ((STEP++)) ;; - # ═══════════════════════════════════════════════════════════════════════════ + # ------------------------------------------------------------------------------ # STEP 24: Container Timezone - # ═══════════════════════════════════════════════════════════════════════════ + # ------------------------------------------------------------------------------ 24) local tz_hint="$_ct_timezone" [[ -z "$tz_hint" ]] && tz_hint="(empty - will use host timezone)" @@ -2541,9 +2541,9 @@ advanced_settings() { fi ;; - # ═══════════════════════════════════════════════════════════════════════════ + # ------------------------------------------------------------------------------ # STEP 25: Container Protection - # ═══════════════════════════════════════════════════════════════════════════ + # ------------------------------------------------------------------------------ 25) local protect_default_flag="--defaultno" [[ "$_protect_ct" == "yes" || "$_protect_ct" == "1" ]] && protect_default_flag="" @@ -2565,9 +2565,9 @@ advanced_settings() { ((STEP++)) ;; - # ═══════════════════════════════════════════════════════════════════════════ + # ------------------------------------------------------------------------------ # STEP 26: Device Node Creation (mknod) - # ═══════════════════════════════════════════════════════════════════════════ + # ------------------------------------------------------------------------------ 26) local mknod_default_flag="--defaultno" [[ "$_enable_mknod" == "1" ]] && mknod_default_flag="" @@ -2589,9 +2589,9 @@ advanced_settings() { ((STEP++)) ;; - # ═══════════════════════════════════════════════════════════════════════════ + # ------------------------------------------------------------------------------ # STEP 27: Mount Filesystems - # ═══════════════════════════════════════════════════════════════════════════ + # ------------------------------------------------------------------------------ 27) local mount_hint="" [[ -n "$_mount_fs" ]] && mount_hint="$_mount_fs" || mount_hint="(none)" @@ -2608,9 +2608,9 @@ advanced_settings() { fi ;; - # ═══════════════════════════════════════════════════════════════════════════ + # ------------------------------------------------------------------------------ # STEP 28: Verbose Mode & Confirmation - # ═══════════════════════════════════════════════════════════════════════════ + # ------------------------------------------------------------------------------ 28) local verbose_default_flag="--defaultno" [[ "$_verbose" == "yes" ]] && verbose_default_flag="" @@ -2676,9 +2676,9 @@ Advanced: esac done - # ═══════════════════════════════════════════════════════════════════════════ + # ------------------------------------------------------------------------------ # Apply all collected values to global variables - # ═══════════════════════════════════════════════════════════════════════════ + # ------------------------------------------------------------------------------ CT_TYPE="$_ct_type" PW="$_pw" CT_ID="$_ct_id" @@ -2895,6 +2895,9 @@ echo_default() { echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}${DISK_SIZE} GB${CL}" echo -e "${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}${CORE_COUNT}${CL}" echo -e "${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}${RAM_SIZE} MiB${CL}" + if [[ "$(dpkg --print-architecture)" == "arm64" ]]; then + echo -e "${INFO}${BOLD}${DGN}Architecture: ${BGN}arm64${CL}" + fi if [[ -n "${var_gpu:-}" && "${var_gpu}" == "yes" ]]; then echo -e "${GPU}${BOLD}${DGN}GPU Passthrough: ${BGN}Enabled${CL}" fi @@ -3425,9 +3428,6 @@ start() { set_std_mode ensure_profile_loaded get_lxc_ip - if [[ "$(dpkg --print-architecture)" == "arm64" ]] && declare -f update_script_arm64 >/dev/null 2>&1; then - update_script_arm64 - fi update_script update_motd_ip cleanup_lxc @@ -3456,9 +3456,6 @@ start() { esac ensure_profile_loaded get_lxc_ip - if [[ "$(dpkg --print-architecture)" == "arm64" ]] && declare -f update_script_arm64 >/dev/null 2>&1; then - update_script_arm64 - fi update_script update_motd_ip cleanup_lxc @@ -4071,7 +4068,11 @@ EOF' msg_warn "Skipping timezone setup – zone '$tz' not found in container" fi - pct exec "$CTID" -- bash -c "apt-get update 2>&1 && apt-get install -y sudo curl mc gnupg2 jq 2>&1" >>"$BUILD_LOG" 2>&1 || { + local _base_pkgs="sudo curl mc gnupg2 jq" + if [[ "${ARCH:-amd64}" == "arm64" ]]; then + _base_pkgs+=" openssh-server wget gcc" + fi + pct exec "$CTID" -- bash -c "apt-get update 2>&1 && apt-get install -y ${_base_pkgs} 2>&1" >>"$BUILD_LOG" 2>&1 || { msg_error "apt-get base packages installation failed" install_exit_code=1 } @@ -5026,13 +5027,15 @@ create_lxc_container() { case "$2" in 12 | 12.*) echo "bookworm" ;; 13 | 13.*) echo "trixie" ;; *) echo "trixie" ;; - esac ;; + esac + ;; alpine) echo "3.22" ;; ubuntu) case "$2" in - 24.04* | noble) echo "noble" ;; 24.10* | oracular) echo "oracular" ;; + 24.04* | noble) echo "noble" ;; 24.10* | oracular) echo "oracular" ;; *) echo "jammy" ;; - esac ;; + esac + ;; *) return 1 ;; esac } @@ -5043,12 +5046,18 @@ create_lxc_container() { download_arm64_template() { local dest="$1" url - mkdir -p "$(dirname "$dest")" || { msg_error "Cannot create template dir."; exit 207; } + mkdir -p "$(dirname "$dest")" || { + msg_error "Cannot create template dir." + exit 207 + } if [[ "$PCT_OSTYPE" == "debian" ]]; then - url=$(curl -fsSL "https://api.github.com/repos/asylumexp/debian-ifupdown2-lxc/releases/latest" \ - | grep -Eo "https://[^\"]*debian-${CUSTOM_TEMPLATE_VARIANT}-arm64-rootfs\.tar\.xz" | head -n1) - [[ -n "$url" ]] || { msg_error "Could not find Debian ${CUSTOM_TEMPLATE_VARIANT} ARM64 template URL."; exit 207; } + url=$(curl -fsSL "https://api.github.com/repos/asylumexp/debian-ifupdown2-lxc/releases/latest" | + grep -Eo "https://[^\"]*debian-${CUSTOM_TEMPLATE_VARIANT}-arm64-rootfs\.tar\.xz" | head -n1) + [[ -n "$url" ]] || { + msg_error "Could not find Debian ${CUSTOM_TEMPLATE_VARIANT} ARM64 template URL." + exit 207 + } else url="https://jenkins.linuxcontainers.org/job/image-${PCT_OSTYPE}/architecture=arm64,release=${CUSTOM_TEMPLATE_VARIANT},variant=default/lastStableBuild/artifact/rootfs.tar.xz" fi diff --git a/misc/core.func b/misc/core.func index 980dfe111..7d44395d6 100644 --- a/misc/core.func +++ b/misc/core.func @@ -351,6 +351,11 @@ arch_check() { sleep 2 exit 106 fi + if [[ "$arch" == "arm64" && "${var_arm64:-}" != "yes" ]]; then + msg_error "This script does not yet support arm64." + sleep 2 + exit 106 + fi } # ------------------------------------------------------------------------------ diff --git a/misc/error_handler.func b/misc/error_handler.func index 39e5e667f..e547a1573 100644 --- a/misc/error_handler.func +++ b/misc/error_handler.func @@ -99,7 +99,7 @@ if ! declare -f explain_exit_code &>/dev/null; then 103) echo "Validation: Shell is not Bash" ;; 104) echo "Validation: Not running as root (or invoked via sudo)" ;; 105) echo "Validation: Proxmox VE version not supported" ;; - 106) echo "Validation: Architecture not supported (ARM / PiMox)" ;; + 106) echo "Validation: Unsupported architecture (requires amd64 or arm64)" ;; 107) echo "Validation: Kernel key parameters unreadable" ;; 108) echo "Validation: Kernel key limits exceeded" ;; 109) echo "Proxmox: No available container ID after max attempts" ;; diff --git a/misc/install.func b/misc/install.func index 4e39b69da..94f005b26 100644 --- a/misc/install.func +++ b/misc/install.func @@ -235,7 +235,6 @@ EOF fi apt_update_safe $STD apt-get -o Dpkg::Options::="--force-confold" -y dist-upgrade - $STD apt-get install -y sudo curl mc gnupg2 openssh-server wget gcc rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED msg_ok "Updated Container OS" post_progress_to_api diff --git a/misc/tools.func b/misc/tools.func index 95ab71bc4..09cd7786e 100644 --- a/misc/tools.func +++ b/misc/tools.func @@ -3651,7 +3651,12 @@ function setup_ffmpeg() { # Binary fallback mode if [[ "$TYPE" == "binary" ]]; then - if ! CURL_TIMEOUT=300 curl_with_retry "https://johnvansickle.com/ffmpeg/releases/ffmpeg-release-amd64-static.tar.xz" "$TMP_DIR/ffmpeg.tar.xz"; then + local ffmpeg_arch + case "$(dpkg --print-architecture 2>/dev/null || echo amd64)" in + arm64) ffmpeg_arch="arm64" ;; + *) ffmpeg_arch="amd64" ;; + esac + if ! CURL_TIMEOUT=300 curl_with_retry "https://johnvansickle.com/ffmpeg/releases/ffmpeg-release-${ffmpeg_arch}-static.tar.xz" "$TMP_DIR/ffmpeg.tar.xz"; then msg_error "Failed to download FFmpeg binary" rm -rf "$TMP_DIR" return 1 @@ -3733,7 +3738,12 @@ function setup_ffmpeg() { # If no source download (either VERSION empty or download failed), use binary if [[ -z "$VERSION" ]]; then msg_info "Setup FFmpeg from pre-built binary" - if ! CURL_TIMEOUT=300 curl_with_retry "https://johnvansickle.com/ffmpeg/releases/ffmpeg-release-amd64-static.tar.xz" "$TMP_DIR/ffmpeg.tar.xz"; then + local ffmpeg_arch + case "$(dpkg --print-architecture 2>/dev/null || echo amd64)" in + arm64) ffmpeg_arch="arm64" ;; + *) ffmpeg_arch="amd64" ;; + esac + if ! CURL_TIMEOUT=300 curl_with_retry "https://johnvansickle.com/ffmpeg/releases/ffmpeg-release-${ffmpeg_arch}-static.tar.xz" "$TMP_DIR/ffmpeg.tar.xz"; then msg_error "Failed to download FFmpeg pre-built binary" rm -rf "$TMP_DIR" return 1 @@ -7706,7 +7716,12 @@ function setup_yq() { msg_info "Setup yq $LATEST_VERSION" fi - if ! curl_with_retry "https://github.com/${GITHUB_REPO}/releases/download/v${LATEST_VERSION}/yq_linux_amd64" "$TMP_DIR/yq"; then + local yq_arch + case "$(dpkg --print-architecture 2>/dev/null || echo amd64)" in + arm64) yq_arch="arm64" ;; + *) yq_arch="amd64" ;; + esac + if ! curl_with_retry "https://github.com/${GITHUB_REPO}/releases/download/v${LATEST_VERSION}/yq_linux_${yq_arch}" "$TMP_DIR/yq"; then msg_error "Failed to download yq" rm -rf "$TMP_DIR" return 1