Merge pull request #1529 from community-scripts/revert-1404-lint-build-func

Revert "[Linting] `misc/build.func` (first pass)"
This commit is contained in:
CanbiZ (MickLesk)
2026-03-02 15:33:16 +01:00
committed by GitHub
2 changed files with 130 additions and 149 deletions

View File

@@ -1 +0,0 @@
external-sources=true

View File

@@ -1,7 +1,6 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# Copyright (c) 2021-2026 community-scripts ORG # Copyright (c) 2021-2026 community-scripts ORG
# Author: tteck (tteckster) | MickLesk | michelroegl-brunner # Author: tteck (tteckster) | MickLesk | michelroegl-brunner
# Co-Author: bandogora
# License: MIT | https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/LICENSE # License: MIT | https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/LICENSE
# ============================================================================== # ==============================================================================
@@ -84,21 +83,20 @@ variables() {
fi fi
} }
# shellcheck source=misc/api.func # Configurable base URL for development — override with COMMUNITY_SCRIPTS_URL
source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/api.func) # See docs/DEV_MODE.md for details
COMMUNITY_SCRIPTS_URL="${COMMUNITY_SCRIPTS_URL:-https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main}"
source <(curl -fsSL "$COMMUNITY_SCRIPTS_URL/misc/api.func")
if command -v curl >/dev/null 2>&1; then if command -v curl >/dev/null 2>&1; then
# shellcheck source=misc/core.func source <(curl -fsSL "$COMMUNITY_SCRIPTS_URL/misc/core.func")
source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/core.func) source <(curl -fsSL "$COMMUNITY_SCRIPTS_URL/misc/error_handler.func")
# shellcheck source=misc/error_handler.func
source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/error_handler.func)
load_functions load_functions
catch_errors catch_errors
elif command -v wget >/dev/null 2>&1; then elif command -v wget >/dev/null 2>&1; then
# shellcheck source=misc/core.func source <(wget -qO- "$COMMUNITY_SCRIPTS_URL/misc/core.func")
source <(wget -qO- https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/core.func) source <(wget -qO- "$COMMUNITY_SCRIPTS_URL/misc/error_handler.func")
# shellcheck source=misc/error_handler.func
source <(wget -qO- https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/error_handler.func)
load_functions load_functions
catch_errors catch_errors
fi fi
@@ -684,7 +682,7 @@ find_host_ssh_keys() {
shopt -s nullglob shopt -s nullglob
if [[ -n "$g" ]]; then if [[ -n "$g" ]]; then
for pat in $g; do cand+=("$pat"); done for pat in $g; do cand+=($pat); done
else else
cand+=(/root/.ssh/authorized_keys /root/.ssh/authorized_keys2) cand+=(/root/.ssh/authorized_keys /root/.ssh/authorized_keys2)
cand+=(/root/.ssh/*.pub) cand+=(/root/.ssh/*.pub)
@@ -701,11 +699,11 @@ find_host_ssh_keys() {
esac esac
# CRLF safe check for host keys # CRLF safe check for host keys
c=$( c=$(tr -d '\r' <"$f" | awk '
tr -d '\r' <"$f" | /^[[:space:]]*#/ {next}
awk '/^[[:space:]]*#/ {next} /^[[:space:]]*$/ {next} {print}' | /^[[:space:]]*$/ {next}
grep -E -c "$re" || true {print}
) ' | grep -E -c '"$re"' || true)
if ((c > 0)); then if ((c > 0)); then
files+=("$f") files+=("$f")
@@ -774,13 +772,11 @@ resolve_ip_from_range() {
local ip2="${ip_end%%/*}" local ip2="${ip_end%%/*}"
local cidr="${ip_start##*/}" local cidr="${ip_start##*/}"
local start_int end_int local start_int=$(ip_to_int "$ip1")
start_int=$(ip_to_int "$ip1") local end_int=$(ip_to_int "$ip2")
end_int=$(ip_to_int "$ip2")
for ((ip_int = start_int; ip_int <= end_int; ip_int++)); do for ((ip_int = start_int; ip_int <= end_int; ip_int++)); do
local ip local ip=$(int_to_ip $ip_int)
ip=$(int_to_ip $ip_int)
msg_info "Checking IP: $ip" msg_info "Checking IP: $ip"
if ! ping -c 1 -W 1 "$ip" >/dev/null 2>&1; then if ! ping -c 1 -W 1 "$ip" >/dev/null 2>&1; then
NET_RESOLVED="$ip/$cidr" NET_RESOLVED="$ip/$cidr"
@@ -1313,7 +1309,7 @@ var_timezone= # Container timezone (e.g. Europe/Berlin, leave empty for
var_tags=community-script var_tags=community-script
var_verbose=no var_verbose=no
# Security (root PW) - empty => autologin # Security (root PW) empty => autologin
# var_pw= # var_pw=
EOF EOF
@@ -1402,7 +1398,7 @@ _is_whitelisted_key() {
_sanitize_value() { _sanitize_value() {
# Disallow Command-Substitution / Shell-Meta # Disallow Command-Substitution / Shell-Meta
case "$1" in case "$1" in
*\$\(* | *\`* | *\;* | *\&* | *\<\(*) *'$('* | *'`'* | *';'* | *'&'* | *'<('*)
echo "" echo ""
return 0 return 0
;; ;;
@@ -1484,7 +1480,7 @@ _build_vars_diff() {
# Build a temporary <app>.vars file from current advanced settings # Build a temporary <app>.vars file from current advanced settings
_build_current_app_vars_tmp() { _build_current_app_vars_tmp() {
tmpf=$(mktemp "/tmp/${NSAPP:-app}.vars.new.XXXXXX") tmpf="$(mktemp /tmp/${NSAPP:-app}.vars.new.XXXXXX)"
# NET/GW # NET/GW
_net="${NET:-}" _net="${NET:-}"
@@ -1647,7 +1643,7 @@ maybe_offer_save_app_defaults() {
while true; do while true; do
local sel local sel
sel="$(whiptail --backtitle "Proxmox VE Helper Scripts" \ sel="$(whiptail --backtitle "Proxmox VE Helper Scripts" \
--title "APP DEFAULTS - ${APP}" \ --title "APP DEFAULTS ${APP}" \
--menu "Differences detected. What do you want to do?" 20 78 10 \ --menu "Differences detected. What do you want to do?" 20 78 10 \
"Update Defaults" "Write new values to ${app_vars_file}" \ "Update Defaults" "Write new values to ${app_vars_file}" \
"Keep Current" "Keep existing defaults (no changes)" \ "Keep Current" "Keep existing defaults (no changes)" \
@@ -1668,7 +1664,7 @@ maybe_offer_save_app_defaults() {
;; ;;
"View Diff") "View Diff")
whiptail --backtitle "Proxmox VE Helper Scripts" \ whiptail --backtitle "Proxmox VE Helper Scripts" \
--title "Diff - ${APP}" \ --title "Diff ${APP}" \
--scrolltext --textbox "$diff_tmp" 25 100 --scrolltext --textbox "$diff_tmp" 25 100
;; ;;
"Cancel" | *) "Cancel" | *)
@@ -1800,17 +1796,14 @@ advanced_settings() {
local OLD_IFS=$IFS local OLD_IFS=$IFS
IFS=$'\n' IFS=$'\n'
for iface_filepath in ${IFACE_FILEPATH_LIST}; do for iface_filepath in ${IFACE_FILEPATH_LIST}; do
local iface_indexes_tmpfile local iface_indexes_tmpfile=$(mktemp -q -u '.iface-XXXX')
iface_indexes_tmpfile=$(mktemp -q -u '.iface-XXXX')
(grep -Pn '^\s*iface' "${iface_filepath}" 2>/dev/null | cut -d':' -f1 && wc -l "${iface_filepath}" 2>/dev/null | cut -d' ' -f1) | awk 'FNR==1 {line=$0; next} {print line":"$0-1; line=$0}' >"${iface_indexes_tmpfile}" 2>/dev/null || true (grep -Pn '^\s*iface' "${iface_filepath}" 2>/dev/null | cut -d':' -f1 && wc -l "${iface_filepath}" 2>/dev/null | cut -d' ' -f1) | awk 'FNR==1 {line=$0; next} {print line":"$0-1; line=$0}' >"${iface_indexes_tmpfile}" 2>/dev/null || true
if [ -f "${iface_indexes_tmpfile}" ]; then if [ -f "${iface_indexes_tmpfile}" ]; then
while read -r pair; do while read -r pair; do
local start end local start=$(echo "${pair}" | cut -d':' -f1)
start=$(echo "${pair}" | cut -d':' -f1) local end=$(echo "${pair}" | cut -d':' -f2)
end=$(echo "${pair}" | cut -d':' -f2)
if awk "NR >= ${start} && NR <= ${end}" "${iface_filepath}" 2>/dev/null | grep -qP '^\s*(bridge[-_](ports|stp|fd|vlan-aware|vids)|ovs_type\s+OVSBridge)\b'; then if awk "NR >= ${start} && NR <= ${end}" "${iface_filepath}" 2>/dev/null | grep -qP '^\s*(bridge[-_](ports|stp|fd|vlan-aware|vids)|ovs_type\s+OVSBridge)\b'; then
local iface_name local iface_name=$(sed "${start}q;d" "${iface_filepath}" | awk '{print $2}')
iface_name=$(sed "${start}q;d" "${iface_filepath}" | awk '{print $2}')
BRIDGES="${iface_name}"$'\n'"${BRIDGES}" BRIDGES="${iface_name}"$'\n'"${BRIDGES}"
fi fi
done <"${iface_indexes_tmpfile}" done <"${iface_indexes_tmpfile}"
@@ -1825,8 +1818,7 @@ advanced_settings() {
if [[ -n "$BRIDGES" ]]; then if [[ -n "$BRIDGES" ]]; then
while IFS= read -r bridge; do while IFS= read -r bridge; do
if [[ -n "$bridge" ]]; then if [[ -n "$bridge" ]]; then
local description local description=$(grep -A 10 "iface $bridge" /etc/network/interfaces 2>/dev/null | grep '^#' | head -n1 | sed 's/^#\s*//')
description=$(grep -A 10 "iface $bridge" /etc/network/interfaces 2>/dev/null | grep '^#' | head -n1 | sed 's/^#\s*//')
BRIDGE_MENU_OPTIONS+=("$bridge" "${description:- }") BRIDGE_MENU_OPTIONS+=("$bridge" "${description:- }")
fi fi
done <<<"$BRIDGES" done <<<"$BRIDGES"
@@ -1838,9 +1830,9 @@ advanced_settings() {
while [ $STEP -le $MAX_STEP ]; do while [ $STEP -le $MAX_STEP ]; do
case $STEP in case $STEP in
# =========================================================================== # ═══════════════════════════════════════════════════════════════════════════
# STEP 1: Container Type # STEP 1: Container Type
# =========================================================================== # ═══════════════════════════════════════════════════════════════════════════
1) 1)
local default_on="ON" local default_on="ON"
local default_off="OFF" local default_off="OFF"
@@ -1863,9 +1855,9 @@ advanced_settings() {
fi fi
;; ;;
# =========================================================================== # ═══════════════════════════════════════════════════════════════════════════
# STEP 2: Root Password # STEP 2: Root Password
# =========================================================================== # ═══════════════════════════════════════════════════════════════════════════
2) 2)
if PW1=$(whiptail --backtitle "Proxmox VE Helper Scripts [Step $STEP/$MAX_STEP]" \ if PW1=$(whiptail --backtitle "Proxmox VE Helper Scripts [Step $STEP/$MAX_STEP]" \
--title "ROOT PASSWORD" \ --title "ROOT PASSWORD" \
@@ -1917,9 +1909,9 @@ advanced_settings() {
fi fi
;; ;;
# =========================================================================== # ═══════════════════════════════════════════════════════════════════════════
# STEP 3: Container ID # STEP 3: Container ID
# =========================================================================== # ═══════════════════════════════════════════════════════════════════════════
3) 3)
if result=$(whiptail --backtitle "Proxmox VE Helper Scripts [Step $STEP/$MAX_STEP]" \ if result=$(whiptail --backtitle "Proxmox VE Helper Scripts [Step $STEP/$MAX_STEP]" \
--title "CONTAINER ID" \ --title "CONTAINER ID" \
@@ -1951,9 +1943,9 @@ advanced_settings() {
fi fi
;; ;;
# =========================================================================== # ═══════════════════════════════════════════════════════════════════════════
# STEP 4: Hostname # STEP 4: Hostname
# =========================================================================== # ═══════════════════════════════════════════════════════════════════════════
4) 4)
if result=$(whiptail --backtitle "Proxmox VE Helper Scripts [Step $STEP/$MAX_STEP]" \ if result=$(whiptail --backtitle "Proxmox VE Helper Scripts [Step $STEP/$MAX_STEP]" \
--title "HOSTNAME" \ --title "HOSTNAME" \
@@ -1974,9 +1966,9 @@ advanced_settings() {
fi fi
;; ;;
# =========================================================================== # ═══════════════════════════════════════════════════════════════════════════
# STEP 5: Disk Size # STEP 5: Disk Size
# =========================================================================== # ═══════════════════════════════════════════════════════════════════════════
5) 5)
if result=$(whiptail --backtitle "Proxmox VE Helper Scripts [Step $STEP/$MAX_STEP]" \ if result=$(whiptail --backtitle "Proxmox VE Helper Scripts [Step $STEP/$MAX_STEP]" \
--title "DISK SIZE" \ --title "DISK SIZE" \
@@ -1995,9 +1987,9 @@ advanced_settings() {
fi fi
;; ;;
# =========================================================================== # ═══════════════════════════════════════════════════════════════════════════
# STEP 6: CPU Cores # STEP 6: CPU Cores
# =========================================================================== # ═══════════════════════════════════════════════════════════════════════════
6) 6)
if result=$(whiptail --backtitle "Proxmox VE Helper Scripts [Step $STEP/$MAX_STEP]" \ if result=$(whiptail --backtitle "Proxmox VE Helper Scripts [Step $STEP/$MAX_STEP]" \
--title "CPU CORES" \ --title "CPU CORES" \
@@ -2016,9 +2008,9 @@ advanced_settings() {
fi fi
;; ;;
# =========================================================================== # ═══════════════════════════════════════════════════════════════════════════
# STEP 7: RAM Size # STEP 7: RAM Size
# =========================================================================== # ═══════════════════════════════════════════════════════════════════════════
7) 7)
if result=$(whiptail --backtitle "Proxmox VE Helper Scripts [Step $STEP/$MAX_STEP]" \ if result=$(whiptail --backtitle "Proxmox VE Helper Scripts [Step $STEP/$MAX_STEP]" \
--title "RAM SIZE" \ --title "RAM SIZE" \
@@ -2037,9 +2029,9 @@ advanced_settings() {
fi fi
;; ;;
# =========================================================================== # ═══════════════════════════════════════════════════════════════════════════
# STEP 8: Network Bridge # STEP 8: Network Bridge
# =========================================================================== # ═══════════════════════════════════════════════════════════════════════════
8) 8)
if [[ ${#BRIDGE_MENU_OPTIONS[@]} -eq 0 ]]; then if [[ ${#BRIDGE_MENU_OPTIONS[@]} -eq 0 ]]; then
# Validate default bridge exists # Validate default bridge exists
@@ -2070,9 +2062,9 @@ advanced_settings() {
fi fi
;; ;;
# =========================================================================== # ═══════════════════════════════════════════════════════════════════════════
# STEP 9: IPv4 Configuration # STEP 9: IPv4 Configuration
# =========================================================================== # ═══════════════════════════════════════════════════════════════════════════
9) 9)
if result=$(whiptail --backtitle "Proxmox VE Helper Scripts [Step $STEP/$MAX_STEP]" \ if result=$(whiptail --backtitle "Proxmox VE Helper Scripts [Step $STEP/$MAX_STEP]" \
--title "IPv4 CONFIGURATION" \ --title "IPv4 CONFIGURATION" \
@@ -2167,9 +2159,9 @@ advanced_settings() {
fi fi
;; ;;
# =========================================================================== # ═══════════════════════════════════════════════════════════════════════════
# STEP 10: IPv6 Configuration # STEP 10: IPv6 Configuration
# =========================================================================== # ═══════════════════════════════════════════════════════════════════════════
10) 10)
if result=$(whiptail --backtitle "Proxmox VE Helper Scripts [Step $STEP/$MAX_STEP]" \ if result=$(whiptail --backtitle "Proxmox VE Helper Scripts [Step $STEP/$MAX_STEP]" \
--title "IPv6 CONFIGURATION" \ --title "IPv6 CONFIGURATION" \
@@ -2242,9 +2234,9 @@ advanced_settings() {
fi fi
;; ;;
# =========================================================================== # ═══════════════════════════════════════════════════════════════════════════
# STEP 11: MTU Size # STEP 11: MTU Size
# =========================================================================== # ═══════════════════════════════════════════════════════════════════════════
11) 11)
if result=$(whiptail --backtitle "Proxmox VE Helper Scripts [Step $STEP/$MAX_STEP]" \ if result=$(whiptail --backtitle "Proxmox VE Helper Scripts [Step $STEP/$MAX_STEP]" \
--title "MTU SIZE" \ --title "MTU SIZE" \
@@ -2262,9 +2254,9 @@ advanced_settings() {
fi fi
;; ;;
# =========================================================================== # ═══════════════════════════════════════════════════════════════════════════
# STEP 12: DNS Search Domain # STEP 12: DNS Search Domain
# =========================================================================== # ═══════════════════════════════════════════════════════════════════════════
12) 12)
if result=$(whiptail --backtitle "Proxmox VE Helper Scripts [Step $STEP/$MAX_STEP]" \ if result=$(whiptail --backtitle "Proxmox VE Helper Scripts [Step $STEP/$MAX_STEP]" \
--title "DNS SEARCH DOMAIN" \ --title "DNS SEARCH DOMAIN" \
@@ -2278,9 +2270,9 @@ advanced_settings() {
fi fi
;; ;;
# =========================================================================== # ═══════════════════════════════════════════════════════════════════════════
# STEP 13: DNS Server # STEP 13: DNS Server
# =========================================================================== # ═══════════════════════════════════════════════════════════════════════════
13) 13)
if result=$(whiptail --backtitle "Proxmox VE Helper Scripts [Step $STEP/$MAX_STEP]" \ if result=$(whiptail --backtitle "Proxmox VE Helper Scripts [Step $STEP/$MAX_STEP]" \
--title "DNS SERVER" \ --title "DNS SERVER" \
@@ -2294,9 +2286,9 @@ advanced_settings() {
fi fi
;; ;;
# =========================================================================== # ═══════════════════════════════════════════════════════════════════════════
# STEP 14: MAC Address # STEP 14: MAC Address
# =========================================================================== # ═══════════════════════════════════════════════════════════════════════════
14) 14)
if result=$(whiptail --backtitle "Proxmox VE Helper Scripts [Step $STEP/$MAX_STEP]" \ if result=$(whiptail --backtitle "Proxmox VE Helper Scripts [Step $STEP/$MAX_STEP]" \
--title "MAC ADDRESS" \ --title "MAC ADDRESS" \
@@ -2314,9 +2306,9 @@ advanced_settings() {
fi fi
;; ;;
# =========================================================================== # ═══════════════════════════════════════════════════════════════════════════
# STEP 15: VLAN Tag # STEP 15: VLAN Tag
# =========================================================================== # ═══════════════════════════════════════════════════════════════════════════
15) 15)
if result=$(whiptail --backtitle "Proxmox VE Helper Scripts [Step $STEP/$MAX_STEP]" \ if result=$(whiptail --backtitle "Proxmox VE Helper Scripts [Step $STEP/$MAX_STEP]" \
--title "VLAN TAG" \ --title "VLAN TAG" \
@@ -2334,9 +2326,9 @@ advanced_settings() {
fi fi
;; ;;
# =========================================================================== # ═══════════════════════════════════════════════════════════════════════════
# STEP 16: Tags # STEP 16: Tags
# =========================================================================== # ═══════════════════════════════════════════════════════════════════════════
16) 16)
if result=$(whiptail --backtitle "Proxmox VE Helper Scripts [Step $STEP/$MAX_STEP]" \ if result=$(whiptail --backtitle "Proxmox VE Helper Scripts [Step $STEP/$MAX_STEP]" \
--title "CONTAINER TAGS" \ --title "CONTAINER TAGS" \
@@ -2356,18 +2348,18 @@ advanced_settings() {
fi fi
;; ;;
# =========================================================================== # ═══════════════════════════════════════════════════════════════════════════
# STEP 17: SSH Settings # STEP 17: SSH Settings
# =========================================================================== # ═══════════════════════════════════════════════════════════════════════════
17) 17)
configure_ssh_settings "Step $STEP/$MAX_STEP" configure_ssh_settings "Step $STEP/$MAX_STEP"
# configure_ssh_settings handles its own flow, always advance # configure_ssh_settings handles its own flow, always advance
((STEP++)) ((STEP++))
;; ;;
# =========================================================================== # ═══════════════════════════════════════════════════════════════════════════
# STEP 18: FUSE Support # STEP 18: FUSE Support
# =========================================================================== # ═══════════════════════════════════════════════════════════════════════════
18) 18)
local fuse_default_flag="--defaultno" local fuse_default_flag="--defaultno"
[[ "$_enable_fuse" == "yes" || "$_enable_fuse" == "1" ]] && fuse_default_flag="" [[ "$_enable_fuse" == "yes" || "$_enable_fuse" == "1" ]] && fuse_default_flag=""
@@ -2389,9 +2381,9 @@ advanced_settings() {
((STEP++)) ((STEP++))
;; ;;
# =========================================================================== # ═══════════════════════════════════════════════════════════════════════════
# STEP 19: TUN/TAP Support # STEP 19: TUN/TAP Support
# =========================================================================== # ═══════════════════════════════════════════════════════════════════════════
19) 19)
local tun_default_flag="--defaultno" local tun_default_flag="--defaultno"
[[ "$_enable_tun" == "yes" || "$_enable_tun" == "1" ]] && tun_default_flag="" [[ "$_enable_tun" == "yes" || "$_enable_tun" == "1" ]] && tun_default_flag=""
@@ -2413,9 +2405,9 @@ advanced_settings() {
((STEP++)) ((STEP++))
;; ;;
# =========================================================================== # ═══════════════════════════════════════════════════════════════════════════
# STEP 20: Nesting Support # STEP 20: Nesting Support
# =========================================================================== # ═══════════════════════════════════════════════════════════════════════════
20) 20)
local nesting_default_flag="" local nesting_default_flag=""
[[ "$_enable_nesting" == "0" || "$_enable_nesting" == "no" ]] && nesting_default_flag="--defaultno" [[ "$_enable_nesting" == "0" || "$_enable_nesting" == "no" ]] && nesting_default_flag="--defaultno"
@@ -2437,9 +2429,9 @@ advanced_settings() {
((STEP++)) ((STEP++))
;; ;;
# =========================================================================== # ═══════════════════════════════════════════════════════════════════════════
# STEP 21: GPU Passthrough # STEP 21: GPU Passthrough
# =========================================================================== # ═══════════════════════════════════════════════════════════════════════════
21) 21)
local gpu_default_flag="--defaultno" local gpu_default_flag="--defaultno"
[[ "$_enable_gpu" == "yes" ]] && gpu_default_flag="" [[ "$_enable_gpu" == "yes" ]] && gpu_default_flag=""
@@ -2461,9 +2453,9 @@ advanced_settings() {
((STEP++)) ((STEP++))
;; ;;
# =========================================================================== # ═══════════════════════════════════════════════════════════════════════════
# STEP 22: Keyctl Support (Docker/systemd) # STEP 22: Keyctl Support (Docker/systemd)
# =========================================================================== # ═══════════════════════════════════════════════════════════════════════════
22) 22)
local keyctl_default_flag="--defaultno" local keyctl_default_flag="--defaultno"
[[ "$_enable_keyctl" == "1" ]] && keyctl_default_flag="" [[ "$_enable_keyctl" == "1" ]] && keyctl_default_flag=""
@@ -2485,9 +2477,9 @@ advanced_settings() {
((STEP++)) ((STEP++))
;; ;;
# =========================================================================== # ═══════════════════════════════════════════════════════════════════════════
# STEP 23: APT Cacher Proxy # STEP 23: APT Cacher Proxy
# =========================================================================== # ═══════════════════════════════════════════════════════════════════════════
23) 23)
local apt_cacher_default_flag="--defaultno" local apt_cacher_default_flag="--defaultno"
[[ "$_apt_cacher" == "yes" ]] && apt_cacher_default_flag="" [[ "$_apt_cacher" == "yes" ]] && apt_cacher_default_flag=""
@@ -2517,9 +2509,9 @@ advanced_settings() {
((STEP++)) ((STEP++))
;; ;;
# =========================================================================== # ═══════════════════════════════════════════════════════════════════════════
# STEP 24: Container Timezone # STEP 24: Container Timezone
# =========================================================================== # ═══════════════════════════════════════════════════════════════════════════
24) 24)
local tz_hint="$_ct_timezone" local tz_hint="$_ct_timezone"
[[ -z "$tz_hint" ]] && tz_hint="(empty - will use host timezone)" [[ -z "$tz_hint" ]] && tz_hint="(empty - will use host timezone)"
@@ -2542,9 +2534,9 @@ advanced_settings() {
fi fi
;; ;;
# =========================================================================== # ═══════════════════════════════════════════════════════════════════════════
# STEP 25: Container Protection # STEP 25: Container Protection
# =========================================================================== # ═══════════════════════════════════════════════════════════════════════════
25) 25)
local protect_default_flag="--defaultno" local protect_default_flag="--defaultno"
[[ "$_protect_ct" == "yes" || "$_protect_ct" == "1" ]] && protect_default_flag="" [[ "$_protect_ct" == "yes" || "$_protect_ct" == "1" ]] && protect_default_flag=""
@@ -2566,9 +2558,9 @@ advanced_settings() {
((STEP++)) ((STEP++))
;; ;;
# =========================================================================== # ═══════════════════════════════════════════════════════════════════════════
# STEP 26: Device Node Creation (mknod) # STEP 26: Device Node Creation (mknod)
# =========================================================================== # ═══════════════════════════════════════════════════════════════════════════
26) 26)
local mknod_default_flag="--defaultno" local mknod_default_flag="--defaultno"
[[ "$_enable_mknod" == "1" ]] && mknod_default_flag="" [[ "$_enable_mknod" == "1" ]] && mknod_default_flag=""
@@ -2590,9 +2582,9 @@ advanced_settings() {
((STEP++)) ((STEP++))
;; ;;
# =========================================================================== # ═══════════════════════════════════════════════════════════════════════════
# STEP 27: Mount Filesystems # STEP 27: Mount Filesystems
# =========================================================================== # ═══════════════════════════════════════════════════════════════════════════
27) 27)
local mount_hint="" local mount_hint=""
[[ -n "$_mount_fs" ]] && mount_hint="$_mount_fs" || mount_hint="(none)" [[ -n "$_mount_fs" ]] && mount_hint="$_mount_fs" || mount_hint="(none)"
@@ -2609,9 +2601,9 @@ advanced_settings() {
fi fi
;; ;;
# =========================================================================== # ═══════════════════════════════════════════════════════════════════════════
# STEP 28: Verbose Mode & Confirmation # STEP 28: Verbose Mode & Confirmation
# =========================================================================== # ═══════════════════════════════════════════════════════════════════════════
28) 28)
local verbose_default_flag="--defaultno" local verbose_default_flag="--defaultno"
[[ "$_verbose" == "yes" ]] && verbose_default_flag="" [[ "$_verbose" == "yes" ]] && verbose_default_flag=""
@@ -2677,9 +2669,9 @@ Advanced:
esac esac
done done
# =========================================================================== # ═══════════════════════════════════════════════════════════════════════════
# Apply all collected values to global variables # Apply all collected values to global variables
# =========================================================================== # ═══════════════════════════════════════════════════════════════════════════
CT_TYPE="$_ct_type" CT_TYPE="$_ct_type"
PW="$_pw" PW="$_pw"
CT_ID="$_ct_id" CT_ID="$_ct_id"
@@ -2805,12 +2797,7 @@ diagnostics_check() {
fi fi
if ! [ -f "/usr/local/community-scripts/diagnostics" ]; then if ! [ -f "/usr/local/community-scripts/diagnostics" ]; then
if ( if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "DIAGNOSTICS" --yesno "Send Diagnostics of LXC Installation?\n\n(This only transmits data without user data, just RAM, CPU, LXC name, ...)" 10 58); then
whiptail --backtitle "Proxmox VE Helper Scripts" \
--title "DIAGNOSTICS" \
--yesno "Send Diagnostics of LXC Installation?\n\n(This only transmits data without user data, just RAM, CPU, LXC name, ...)" \
10 58
); then
cat <<EOF >/usr/local/community-scripts/diagnostics cat <<EOF >/usr/local/community-scripts/diagnostics
DIAGNOSTICS=yes DIAGNOSTICS=yes
@@ -3497,8 +3484,7 @@ msg_menu() {
# - Otherwise: shows update/setting menu and runs update_script with cleanup # - Otherwise: shows update/setting menu and runs update_script with cleanup
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
start() { start() {
# shellcheck source=misc/tools.func source <(curl -fsSL "$COMMUNITY_SCRIPTS_URL/misc/tools.func")
source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/tools.func)
if command -v pveversion >/dev/null 2>&1; then if command -v pveversion >/dev/null 2>&1; then
install_script || return 0 install_script || return 0
return 0 return 0
@@ -3628,11 +3614,10 @@ build_container() {
TEMP_DIR=$(mktemp -d) TEMP_DIR=$(mktemp -d)
pushd "$TEMP_DIR" >/dev/null pushd "$TEMP_DIR" >/dev/null
if [ "$var_os" == "alpine" ]; then if [ "$var_os" == "alpine" ]; then
FUNCTIONS_FILE_PATH=$(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/alpine-install.func) export FUNCTIONS_FILE_PATH="$(curl -fsSL "$COMMUNITY_SCRIPTS_URL/misc/alpine-install.func")"
else else
FUNCTIONS_FILE_PATH=$(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/install.func) export FUNCTIONS_FILE_PATH="$(curl -fsSL "$COMMUNITY_SCRIPTS_URL/misc/install.func")"
fi fi
export FUNCTIONS_FILE_PATH
# Core exports for install.func # Core exports for install.func
export DIAGNOSTICS="$DIAGNOSTICS" export DIAGNOSTICS="$DIAGNOSTICS"
@@ -3784,8 +3769,7 @@ $PCT_OPTIONS_STRING"
NVIDIA_DEVICES=() NVIDIA_DEVICES=()
# Store PCI info to avoid multiple calls # Store PCI info to avoid multiple calls
local pci_vga_info local pci_vga_info=$(lspci -nn 2>/dev/null | grep -E "VGA|Display|3D")
pci_vga_info=$(lspci -nn 2>/dev/null | grep -E "VGA|Display|3D")
# Check for Intel GPU - look for Intel vendor ID [8086] # Check for Intel GPU - look for Intel vendor ID [8086]
if echo "$pci_vga_info" | grep -q "\[8086:"; then if echo "$pci_vga_info" | grep -q "\[8086:"; then
@@ -4055,9 +4039,8 @@ EOF
fi fi
# Function to get correct GID inside container # Function to get correct GID inside container
get_container_gid() { get_container_gid() {
local group gid local group="$1"
group="$1" local gid=$(pct exec "$CTID" -- getent group "$group" 2>/dev/null | cut -d: -f3)
gid=$(pct exec "$CTID" -- getent group "$group" 2>/dev/null | cut -d: -f3)
echo "${gid:-44}" # Default to 44 if not found echo "${gid:-44}" # Default to 44 if not found
} }
@@ -4118,7 +4101,7 @@ EOF'
# Create /etc/timezone for backwards compatibility with older scripts # Create /etc/timezone for backwards compatibility with older scripts
pct exec "$CTID" -- bash -c "tz='$tz'; ln -sf \"/usr/share/zoneinfo/\$tz\" /etc/localtime && echo \"\$tz\" >/etc/timezone || true" pct exec "$CTID" -- bash -c "tz='$tz'; ln -sf \"/usr/share/zoneinfo/\$tz\" /etc/localtime && echo \"\$tz\" >/etc/timezone || true"
else else
msg_warn "Skipping timezone setup - zone '$tz' not found in container" msg_warn "Skipping timezone setup zone '$tz' not found in container"
fi fi
pct exec "$CTID" -- bash -c "apt-get update >/dev/null && apt-get install -y sudo curl mc gnupg2 jq >/dev/null" || { pct exec "$CTID" -- bash -c "apt-get update >/dev/null && apt-get install -y sudo curl mc gnupg2 jq >/dev/null" || {
@@ -4140,7 +4123,7 @@ EOF'
set +Eeuo pipefail # Disable ALL error handling temporarily set +Eeuo pipefail # Disable ALL error handling temporarily
trap - ERR # Remove ERR trap completely trap - ERR # Remove ERR trap completely
lxc-attach -n "$CTID" -- bash -c "curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/install/${var_install}.sh" lxc-attach -n "$CTID" -- bash -c "$(curl -fsSL "$COMMUNITY_SCRIPTS_URL/install/${var_install}.sh")"
local lxc_exit=$? local lxc_exit=$?
set -Eeuo pipefail # Re-enable error handling set -Eeuo pipefail # Re-enable error handling
@@ -4232,7 +4215,7 @@ EOF'
else else
msg_dev "Container ${CTID} kept for debugging" msg_dev "Container ${CTID} kept for debugging"
fi fi
exit "$install_exit_code" exit $install_exit_code
fi fi
# Prompt user for cleanup with 60s timeout # Prompt user for cleanup with 60s timeout
@@ -4392,12 +4375,11 @@ EOF'
source <(curl -fsSL "$COMMUNITY_SCRIPTS_URL/misc/install.func") source <(curl -fsSL "$COMMUNITY_SCRIPTS_URL/misc/install.func")
declare -f motd_ssh >/dev/null 2>&1 && motd_ssh || true declare -f motd_ssh >/dev/null 2>&1 && motd_ssh || true
" >/dev/null 2>&1; then " >/dev/null 2>&1; then
local ct_ip local ct_ip=$(pct exec "$CTID" ip a s dev eth0 2>/dev/null | awk '/inet / {print $2}' | cut -d/ -f1)
ct_ip=$(pct exec "$CTID" ip a s dev eth0 2>/dev/null | awk '/inet / {print $2}' | cut -d/ -f1)
echo -e "${BFR}${CM}${GN}MOTD/SSH ready - SSH into container: ssh root@${ct_ip}${CL}" echo -e "${BFR}${CM}${GN}MOTD/SSH ready - SSH into container: ssh root@${ct_ip}${CL}"
fi fi
fi fi
exit "$install_exit_code" exit $install_exit_code
;; ;;
3) 3)
# Retry with verbose mode # Retry with verbose mode
@@ -4408,8 +4390,7 @@ EOF'
echo "" echo ""
# Get new container ID # Get new container ID
local old_ctid="$CTID" local old_ctid="$CTID"
CTID=$(get_valid_container_id "$CTID") export CTID=$(get_valid_container_id "$CTID")
export CTID
export VERBOSE="yes" export VERBOSE="yes"
export var_verbose="yes" export var_verbose="yes"
@@ -4506,10 +4487,9 @@ EOF'
local old_ctid="$CTID" local old_ctid="$CTID"
local old_ram="$RAM_SIZE" local old_ram="$RAM_SIZE"
local old_cpu="$CORE_COUNT" local old_cpu="$CORE_COUNT"
CTID=$(get_valid_container_id "$CTID") export CTID=$(get_valid_container_id "$CTID")
export CTID export RAM_SIZE=$((RAM_SIZE * 2))
export RAM_SIZE=$((RAM_SIZE * 3 / 2)) export CORE_COUNT=$((CORE_COUNT * 2))
export CORE_COUNT=$((CORE_COUNT + 1))
export var_ram="$RAM_SIZE" export var_ram="$RAM_SIZE"
export var_cpu="$CORE_COUNT" export var_cpu="$CORE_COUNT"
export VERBOSE="yes" export VERBOSE="yes"
@@ -4556,13 +4536,13 @@ EOF'
if [[ "$handled" == false ]]; then if [[ "$handled" == false ]]; then
echo -e "\n${TAB}${YW}Invalid option. Container ${CTID} kept.${CL}" echo -e "\n${TAB}${YW}Invalid option. Container ${CTID} kept.${CL}"
exit "$install_exit_code" exit $install_exit_code
fi fi
;; ;;
*)
echo -e "\n${TAB}${YW}Invalid option. Container ${CTID} kept.${CL}"
exit "$install_exit_code"
;;
esac esac
else else
# Timeout - auto-remove # Timeout - auto-remove
@@ -4574,7 +4554,11 @@ EOF'
msg_ok "Container ${CTID} removed" msg_ok "Container ${CTID} removed"
fi fi
exit "$install_exit_code" # Force one final status update attempt after cleanup
# This ensures status is updated even if the first attempt failed (e.g., HTTP 400)
post_update_to_api "failed" "$install_exit_code" "force"
exit $install_exit_code
fi fi
# Clean up host-side capture log (not needed on success, already in combined_log on failure) # Clean up host-side capture log (not needed on success, already in combined_log on failure)
@@ -4665,9 +4649,8 @@ fix_gpu_gids() {
msg_info "Detecting and setting correct GPU group IDs" msg_info "Detecting and setting correct GPU group IDs"
# Get actual GIDs from container # Get actual GIDs from container
local video_gid render_gid local video_gid=$(pct exec "$CTID" -- sh -c "getent group video 2>/dev/null | cut -d: -f3")
video_gid=$(pct exec "$CTID" -- sh -c "getent group video 2>/dev/null | cut -d: -f3") local render_gid=$(pct exec "$CTID" -- sh -c "getent group render 2>/dev/null | cut -d: -f3")
render_gid=$(pct exec "$CTID" -- sh -c "getent group render 2>/dev/null | cut -d: -f3")
# Create groups if they don't exist # Create groups if they don't exist
if [[ -z "$video_gid" ]]; then if [[ -z "$video_gid" ]]; then
@@ -4763,11 +4746,10 @@ select_storage() {
while read -r TAG TYPE _ TOTAL USED FREE _; do while read -r TAG TYPE _ TOTAL USED FREE _; do
[[ -n "$TAG" && -n "$TYPE" ]] || continue [[ -n "$TAG" && -n "$TYPE" ]] || continue
local DISPLAY USED_FMT FREE_FMT INFO local DISPLAY="${TAG} (${TYPE})"
DISPLAY="${TAG} (${TYPE})" local USED_FMT=$(numfmt --to=iec --from-unit=1024 --format %.1f <<<"$USED")
USED_FMT=$(numfmt --to=iec --from-unit=1024 --format %.1f <<<"$USED") local FREE_FMT=$(numfmt --to=iec --from-unit=1024 --format %.1f <<<"$FREE")
FREE_FMT=$(numfmt --to=iec --from-unit=1024 --format %.1f <<<"$FREE") local INFO="Free: ${FREE_FMT}B Used: ${USED_FMT}B"
INFO="Free: ${FREE_FMT}B Used: ${USED_FMT}B"
STORAGE_MAP["$DISPLAY"]="$TAG" STORAGE_MAP["$DISPLAY"]="$TAG"
MENU+=("$DISPLAY" "$INFO" "OFF") MENU+=("$DISPLAY" "$INFO" "OFF")
((${#DISPLAY} > COL_WIDTH)) && COL_WIDTH=${#DISPLAY} ((${#DISPLAY} > COL_WIDTH)) && COL_WIDTH=${#DISPLAY}
@@ -5175,7 +5157,7 @@ create_lxc_container() {
fi fi
fi fi
TEMPLATE_PATH=$(pvesm path "$TEMPLATE_STORAGE:vztmpl/$TEMPLATE" 2>/dev/null || true) TEMPLATE_PATH="$(pvesm path $TEMPLATE_STORAGE:vztmpl/$TEMPLATE 2>/dev/null || true)"
if [[ -z "$TEMPLATE_PATH" ]]; then if [[ -z "$TEMPLATE_PATH" ]]; then
TEMPLATE_BASE=$(awk -v s="$TEMPLATE_STORAGE" '$1==s {f=1} f && /path/ {print $2; exit}' /etc/pve/storage.cfg) TEMPLATE_BASE=$(awk -v s="$TEMPLATE_STORAGE" '$1==s {f=1} f && /path/ {print $2; exit}' /etc/pve/storage.cfg)
[[ -n "$TEMPLATE_BASE" ]] && TEMPLATE_PATH="$TEMPLATE_BASE/template/cache/$TEMPLATE" [[ -n "$TEMPLATE_BASE" ]] && TEMPLATE_PATH="$TEMPLATE_BASE/template/cache/$TEMPLATE"
@@ -5235,7 +5217,7 @@ create_lxc_container() {
TEMPLATE_SOURCE="online" TEMPLATE_SOURCE="online"
fi fi
TEMPLATE_PATH=$(pvesm path "$TEMPLATE_STORAGE:vztmpl/$TEMPLATE" 2>/dev/null || true) TEMPLATE_PATH="$(pvesm path $TEMPLATE_STORAGE:vztmpl/$TEMPLATE 2>/dev/null || true)"
if [[ -z "$TEMPLATE_PATH" ]]; then if [[ -z "$TEMPLATE_PATH" ]]; then
TEMPLATE_BASE=$(awk -v s="$TEMPLATE_STORAGE" '$1==s {f=1} f && /path/ {print $2; exit}' /etc/pve/storage.cfg) TEMPLATE_BASE=$(awk -v s="$TEMPLATE_STORAGE" '$1==s {f=1} f && /path/ {print $2; exit}' /etc/pve/storage.cfg)
[[ -n "$TEMPLATE_BASE" ]] && TEMPLATE_PATH="$TEMPLATE_BASE/template/cache/$TEMPLATE" [[ -n "$TEMPLATE_BASE" ]] && TEMPLATE_PATH="$TEMPLATE_BASE/template/cache/$TEMPLATE"
@@ -5271,21 +5253,21 @@ create_lxc_container() {
NEED_DOWNLOAD=0 NEED_DOWNLOAD=0
if [[ ! -f "$TEMPLATE_PATH" ]]; then if [[ ! -f "$TEMPLATE_PATH" ]]; then
msg_info "Template not present locally - will download." msg_info "Template not present locally will download."
NEED_DOWNLOAD=1 NEED_DOWNLOAD=1
elif [[ ! -r "$TEMPLATE_PATH" ]]; then elif [[ ! -r "$TEMPLATE_PATH" ]]; then
msg_error "Template file exists but is not readable - check permissions." msg_error "Template file exists but is not readable check permissions."
exit 221 exit 221
elif [[ "$(stat -c%s "$TEMPLATE_PATH")" -lt 1000000 ]]; then elif [[ "$(stat -c%s "$TEMPLATE_PATH")" -lt 1000000 ]]; then
if [[ -n "$ONLINE_TEMPLATE" ]]; then if [[ -n "$ONLINE_TEMPLATE" ]]; then
msg_warn "Template file too small (<1MB) - re-downloading." msg_warn "Template file too small (<1MB) re-downloading."
NEED_DOWNLOAD=1 NEED_DOWNLOAD=1
else else
msg_warn "Template looks too small, but no online version exists. Keeping local file." msg_warn "Template looks too small, but no online version exists. Keeping local file."
fi fi
elif ! tar -tf "$TEMPLATE_PATH" &>/dev/null; then elif ! tar -tf "$TEMPLATE_PATH" &>/dev/null; then
if [[ -n "$ONLINE_TEMPLATE" ]]; then if [[ -n "$ONLINE_TEMPLATE" ]]; then
msg_warn "Template appears corrupted - re-downloading." msg_warn "Template appears corrupted re-downloading."
NEED_DOWNLOAD=1 NEED_DOWNLOAD=1
else else
msg_warn "Template appears corrupted, but no online version exists. Keeping local file." msg_warn "Template appears corrupted, but no online version exists. Keeping local file."
@@ -5346,7 +5328,7 @@ create_lxc_container() {
# PCT_OPTIONS is now a string (exported from build_container) # PCT_OPTIONS is now a string (exported from build_container)
# Add rootfs if not already specified # Add rootfs if not already specified
if [[ ! $PCT_OPTIONS =~ "-rootfs" ]]; then if [[ ! "$PCT_OPTIONS" =~ "-rootfs" ]]; then
PCT_OPTIONS="$PCT_OPTIONS PCT_OPTIONS="$PCT_OPTIONS
-rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8}" -rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8}"
fi fi
@@ -5387,13 +5369,13 @@ create_lxc_container() {
# Validate template before pct create (while holding lock) # Validate template before pct create (while holding lock)
if [[ ! -s "$TEMPLATE_PATH" || "$(stat -c%s "$TEMPLATE_PATH" 2>/dev/null || echo 0)" -lt 1000000 ]]; then if [[ ! -s "$TEMPLATE_PATH" || "$(stat -c%s "$TEMPLATE_PATH" 2>/dev/null || echo 0)" -lt 1000000 ]]; then
msg_info "Template file missing or too small - downloading" msg_info "Template file missing or too small downloading"
rm -f "$TEMPLATE_PATH" rm -f "$TEMPLATE_PATH"
pveam download "$TEMPLATE_STORAGE" "$TEMPLATE" >/dev/null 2>&1 pveam download "$TEMPLATE_STORAGE" "$TEMPLATE" >/dev/null 2>&1
msg_ok "Template downloaded" msg_ok "Template downloaded"
elif ! tar -tf "$TEMPLATE_PATH" &>/dev/null; then elif ! tar -tf "$TEMPLATE_PATH" &>/dev/null; then
if [[ -n "$ONLINE_TEMPLATE" ]]; then if [[ -n "$ONLINE_TEMPLATE" ]]; then
msg_info "Template appears corrupted - re-downloading" msg_info "Template appears corrupted re-downloading"
rm -f "$TEMPLATE_PATH" rm -f "$TEMPLATE_PATH"
pveam download "$TEMPLATE_STORAGE" "$TEMPLATE" >/dev/null 2>&1 pveam download "$TEMPLATE_STORAGE" "$TEMPLATE" >/dev/null 2>&1
msg_ok "Template re-downloaded" msg_ok "Template re-downloaded"
@@ -5414,7 +5396,7 @@ create_lxc_container() {
# Check if template issue - retry with fresh download # Check if template issue - retry with fresh download
if grep -qiE 'unable to open|corrupt|invalid' "$LOGFILE"; then if grep -qiE 'unable to open|corrupt|invalid' "$LOGFILE"; then
msg_info "Template may be corrupted - re-downloading" msg_info "Template may be corrupted re-downloading"
rm -f "$TEMPLATE_PATH" rm -f "$TEMPLATE_PATH"
pveam download "$TEMPLATE_STORAGE" "$TEMPLATE" >/dev/null 2>&1 pveam download "$TEMPLATE_STORAGE" "$TEMPLATE" >/dev/null 2>&1
msg_ok "Template re-downloaded" msg_ok "Template re-downloaded"
@@ -5438,7 +5420,7 @@ create_lxc_container() {
# Local fallback also failed - check for LXC stack version issue # Local fallback also failed - check for LXC stack version issue
if grep -qiE 'unsupported .* version' "$LOGFILE"; then if grep -qiE 'unsupported .* version' "$LOGFILE"; then
echo echo
echo "pct reported 'unsupported ... version' - your LXC stack might be too old for this template." echo "pct reported 'unsupported ... version' your LXC stack might be too old for this template."
echo "We can try to upgrade 'pve-container' and 'lxc-pve' now and retry automatically." echo "We can try to upgrade 'pve-container' and 'lxc-pve' now and retry automatically."
offer_lxc_stack_upgrade_and_maybe_retry "yes" offer_lxc_stack_upgrade_and_maybe_retry "yes"
rc=$? rc=$?
@@ -5470,7 +5452,7 @@ create_lxc_container() {
# Already on local storage and still failed - check LXC stack version # Already on local storage and still failed - check LXC stack version
if grep -qiE 'unsupported .* version' "$LOGFILE"; then if grep -qiE 'unsupported .* version' "$LOGFILE"; then
echo echo
echo "pct reported 'unsupported ... version' - your LXC stack might be too old for this template." echo "pct reported 'unsupported ... version' your LXC stack might be too old for this template."
echo "We can try to upgrade 'pve-container' and 'lxc-pve' now and retry automatically." echo "We can try to upgrade 'pve-container' and 'lxc-pve' now and retry automatically."
offer_lxc_stack_upgrade_and_maybe_retry "yes" offer_lxc_stack_upgrade_and_maybe_retry "yes"
rc=$? rc=$?