From 69a5ac3a566f2890abf9af5de8dc4016e697ee92 Mon Sep 17 00:00:00 2001 From: Michel Roegl-Brunner Date: Fri, 5 Dec 2025 16:03:28 +0100 Subject: [PATCH] Nump core --- scripts/core/build.func | 91 ++++++++++++++++----------------- scripts/core/error-handler.func | 55 +++++++++++--------- scripts/core/tools.func | 15 ++++-- 3 files changed, 86 insertions(+), 75 deletions(-) diff --git a/scripts/core/build.func b/scripts/core/build.func index 2d81be9..1b11f66 100755 --- a/scripts/core/build.func +++ b/scripts/core/build.func @@ -2441,10 +2441,15 @@ build_container() { if echo "$pci_vga_info" | grep -q "\[10de:"; then msg_custom "🎮" "${GN}" "Detected NVIDIA GPU" - # Simple passthrough - just bind /dev/nvidia* devices if they exist - for d in /dev/nvidia* /dev/nvidiactl /dev/nvidia-modeset /dev/nvidia-uvm /dev/nvidia-uvm-tools; do - [[ -e "$d" ]] && NVIDIA_DEVICES+=("$d") + for d in /dev/nvidia*; do + [[ -c "$d" ]] && NVIDIA_DEVICES+=("$d") done + # Also check for devices inside /dev/nvidia-caps/ directory + if [[ -d /dev/nvidia-caps ]]; then + for d in /dev/nvidia-caps/*; do + [[ -c "$d" ]] && NVIDIA_DEVICES+=("$d") + done + fi if [[ ${#NVIDIA_DEVICES[@]} -gt 0 ]]; then msg_custom "🎮" "${GN}" "Found ${#NVIDIA_DEVICES[@]} NVIDIA device(s) for passthrough" @@ -2954,15 +2959,14 @@ fix_gpu_gids() { # For privileged containers: also fix permissions inside container if [[ "$CT_TYPE" == "0" ]]; then - pct exec "$CTID" -- bash -c " + pct exec "$CTID" -- sh -c " if [ -d /dev/dri ]; then for dev in /dev/dri/*; do if [ -e \"\$dev\" ]; then - if [[ \"\$dev\" =~ renderD ]]; then - chgrp ${render_gid} \"\$dev\" 2>/dev/null || true - else - chgrp ${video_gid} \"\$dev\" 2>/dev/null || true - fi + case \"\$dev\" in + *renderD*) chgrp ${render_gid} \"\$dev\" 2>/dev/null || true ;; + *) chgrp ${video_gid} \"\$dev\" 2>/dev/null || true ;; + esac chmod 660 \"\$dev\" 2>/dev/null || true fi done @@ -3211,42 +3215,26 @@ create_lxc_container() { fi fi - # Validate content types - msg_info "Validating content types of storage '$CONTAINER_STORAGE'" - STORAGE_CONTENT=$(grep -A4 -E "^(zfspool|dir|lvmthin|lvm|linstor): $CONTAINER_STORAGE" /etc/pve/storage.cfg | grep content | awk '{$1=""; print $0}' | xargs) - msg_debug "Storage '$CONTAINER_STORAGE' has content types: $STORAGE_CONTENT" + msg_info "Validating storage '$CONTAINER_STORAGE'" + STORAGE_TYPE=$(grep -E "^[^:]+: $CONTAINER_STORAGE$" /etc/pve/storage.cfg | cut -d: -f1 | head -1) - # Check storage type for special handling - STORAGE_TYPE=$(grep -E "^[^:]+: $CONTAINER_STORAGE$" /etc/pve/storage.cfg | cut -d: -f1) - if [[ "$STORAGE_TYPE" == "linstor" ]]; then - msg_info "Detected LINSTOR storage - verifying cluster connectivity" - if ! pvesm status -storage "$CONTAINER_STORAGE" &>/dev/null; then - msg_error "LINSTOR storage '$CONTAINER_STORAGE' not accessible. Check LINSTOR cluster health." - exit 217 - fi - fi - - grep -qw "rootdir" <<<"$STORAGE_CONTENT" || { - msg_error "Storage '$CONTAINER_STORAGE' does not support 'rootdir'. Cannot create LXC." - exit 217 - } - $STD msg_ok "Storage '$CONTAINER_STORAGE' supports 'rootdir'" - - msg_info "Validating content types of template storage '$TEMPLATE_STORAGE'" - TEMPLATE_CONTENT=$(grep -A4 -E "^[^:]+: $TEMPLATE_STORAGE" /etc/pve/storage.cfg | grep content | awk '{$1=""; print $0}' | xargs) - msg_debug "Template storage '$TEMPLATE_STORAGE' has content types: $TEMPLATE_CONTENT" - - # Check if template storage is LINSTOR (may need special handling) - TEMPLATE_TYPE=$(grep -E "^[^:]+: $TEMPLATE_STORAGE$" /etc/pve/storage.cfg | cut -d: -f1) - if [[ "$TEMPLATE_TYPE" == "linstor" ]]; then - msg_info "Template storage uses LINSTOR - ensuring resource availability" - fi - - if ! grep -qw "vztmpl" <<<"$TEMPLATE_CONTENT"; then - msg_warn "Template storage '$TEMPLATE_STORAGE' does not declare 'vztmpl'. This may cause pct create to fail." - else - $STD msg_ok "Template storage '$TEMPLATE_STORAGE' supports 'vztmpl'" + case "$STORAGE_TYPE" in + iscsidirect) exit 212 ;; + iscsi | zfs) exit 213 ;; + cephfs) exit 219 ;; + pbs) exit 224 ;; + linstor | rbd | nfs | cifs) + pvesm status -storage "$CONTAINER_STORAGE" &>/dev/null || exit 217 + ;; + esac + + pvesm status -content rootdir 2>/dev/null | awk 'NR>1{print $1}' | grep -qx "$CONTAINER_STORAGE" || exit 213Add a comment on line R3227Add diff commentMarkdown input: edit mode selected.WritePreviewAdd a suggestionHeadingBoldItalicQuoteCodeLinkUnordered listNumbered listTask listMentionReferenceSaved repliesAdd FilesPaste, drop, or click to add filesCancelCommentStart a reviewReturn to code + msg_ok "Storage '$CONTAINER_STORAGE' ($STORAGE_TYPE) validated" + + if ! pvesm status -content vztmpl 2>/dev/null | awk 'NR>1{print $1}' | grep -qx "$TEMPLATE_STORAGE"; then + msg_warn "Template storage '$TEMPLATE_STORAGE' may not support 'vztmpl'" fi + msg_ok "Template storage '$TEMPLATE_STORAGE' validated" # Free space check STORAGE_FREE=$(pvesm status | awk -v s="$CONTAINER_STORAGE" '$1 == s { print $6 }') @@ -3261,7 +3249,7 @@ create_lxc_container() { msg_info "Checking cluster quorum" if ! pvecm status | awk -F':' '/^Quorate/ { exit ($2 ~ /Yes/) ? 0 : 1 }'; then msg_error "Cluster is not quorate. Start all nodes or configure quorum device (QDevice)." - exit 201 + exit 210 fi msg_ok "Cluster is quorate" fi @@ -3417,6 +3405,15 @@ create_lxc_container() { ONLINE_TEMPLATE="" [[ ${#ONLINE_TEMPLATES[@]} -gt 0 ]] && ONLINE_TEMPLATE="${ONLINE_TEMPLATES[-1]}" + if [[ ${#ONLINE_TEMPLATES[@]} -gt 0 ]]; then + count=0 + for idx in "${!ONLINE_TEMPLATES[@]}"; do + ((count++)) + [[ $count -ge 3 ]] && break + done + ONLINE_TEMPLATE="${ONLINE_TEMPLATES[$idx]}" + fi + if [[ ${#LOCAL_TEMPLATES[@]} -gt 0 ]]; then TEMPLATE="${LOCAL_TEMPLATES[-1]}" TEMPLATE_SOURCE="local" @@ -3554,7 +3551,7 @@ create_lxc_container() { } flock -w 60 9 || { msg_error "Timeout while waiting for template lock." - exit 202 + exit 211 } LOGFILE="/tmp/pct_create_${CTID}_$(date +%Y%m%d_%H%M%S)_${SESSION_ID}.log" @@ -3604,11 +3601,11 @@ create_lxc_container() { 2) echo "Upgrade was declined. Please update and re-run: apt update && apt install --only-upgrade pve-container lxc-pve" - exit 213 + exit 231 ;; 3) echo "Upgrade and/or retry failed. Please inspect: $LOGFILE" - exit 213 + exit 231 ;; esac else diff --git a/scripts/core/error-handler.func b/scripts/core/error-handler.func index 9ad4f6d..e227c39 100644 --- a/scripts/core/error-handler.func +++ b/scripts/core/error-handler.func @@ -79,38 +79,43 @@ explain_exit_code() { 234) echo "PostgreSQL: Fatal error in query / syntax" ;; # --- MySQL / MariaDB --- - 260) echo "MySQL/MariaDB: Connection failed (server not running / wrong socket)" ;; - 261) echo "MySQL/MariaDB: Authentication failed (bad user/password)" ;; - 262) echo "MySQL/MariaDB: Database does not exist" ;; - 263) echo "MySQL/MariaDB: Fatal error in query / syntax" ;; + 241) echo "MySQL/MariaDB: Connection failed (server not running / wrong socket)" ;; + 242) echo "MySQL/MariaDB: Authentication failed (bad user/password)" ;; + 243) echo "MySQL/MariaDB: Database does not exist" ;; + 244) echo "MySQL/MariaDB: Fatal error in query / syntax" ;; # --- MongoDB --- 251) echo "MongoDB: Connection failed (server not running)" ;; 252) echo "MongoDB: Authentication failed (bad user/password)" ;; 253) echo "MongoDB: Database not found" ;; + 254) echo "MongoDB: Fatal query error" ;; # --- Proxmox Custom Codes --- - 200) echo "Custom: Failed to create lock file" ;; - 201) echo "Custom: Cluster not quorate" ;; - 202) echo "Custom: Timeout waiting for template lock (concurrent download in progress)" ;; - 203) echo "Custom: Missing CTID variable" ;; - 204) echo "Custom: Missing PCT_OSTYPE variable" ;; - 205) echo "Custom: Invalid CTID (<100)" ;; - 206) echo "Custom: CTID already in use (check 'pct list' and /etc/pve/lxc/)" ;; - 207) echo "Custom: Password contains unescaped special characters (-, /, \\, *, etc.)" ;; - 208) echo "Custom: Invalid configuration (DNS/MAC/Network format error)" ;; - 209) echo "Custom: Container creation failed (check logs for pct create output)" ;; - 213) echo "Custom: LXC stack upgrade/retry failed (outdated pve-container - check https://github.com/community-scripts/ProxmoxVE/discussions/8126)" ;; - 214) echo "Custom: Not enough storage space" ;; - 215) echo "Custom: Container created but not listed (ghost state - check /etc/pve/lxc/)" ;; - 216) echo "Custom: RootFS entry missing in config (incomplete creation)" ;; - 217) echo "Custom: Storage does not support rootdir (check storage capabilities)" ;; - 218) echo "Custom: Template file corrupted or incomplete download (size <1MB or invalid archive)" ;; - 220) echo "Custom: Unable to resolve template path" ;; - 221) echo "Custom: Template file exists but not readable (check file permissions)" ;; - 222) echo "Custom: Template download failed after 3 attempts (network/storage issue)" ;; - 223) echo "Custom: Template not available after download (storage sync issue)" ;; - 225) echo "Custom: No template available for OS/Version (check 'pveam available')" ;; + 200) echo "Proxmox: Failed to create lock file" ;; + 203) echo "Proxmox: Missing CTID variable" ;; + 204) echo "Proxmox: Missing PCT_OSTYPE variable" ;; + 205) echo "Proxmox: Invalid CTID (<100)" ;; + 206) echo "Proxmox: CTID already in use" ;; + 207) echo "Proxmox: Password contains unescaped special characters" ;; + 208) echo "Proxmox: Invalid configuration (DNS/MAC/Network format)" ;; + 209) echo "Proxmox: Container creation failed" ;; + 210) echo "Proxmox: Cluster not quorate" ;; + 211) echo "Proxmox: Timeout waiting for template lock" ;; + 212) echo "Proxmox: Storage type 'iscsidirect' does not support containers (VMs only)" ;; + 213) echo "Proxmox: Storage type does not support 'rootdir' content" ;; + 214) echo "Proxmox: Not enough storage space" ;; + 215) echo "Proxmox: Container created but not listed (ghost state)" ;; + 216) echo "Proxmox: RootFS entry missing in config" ;; + 217) echo "Proxmox: Storage not accessible" ;; + 219) echo "Proxmox: CephFS does not support containers - use RBD" ;; + 224) echo "Proxmox: PBS storage is for backups only" ;; + 218) echo "Proxmox: Template file corrupted or incomplete" ;; + 220) echo "Proxmox: Unable to resolve template path" ;; + 221) echo "Proxmox: Template file not readable" ;; + 222) echo "Proxmox: Template download failed" ;; + 223) echo "Proxmox: Template not available after download" ;; + 225) echo "Proxmox: No template available for OS/Version" ;; + 231) echo "Proxmox: LXC stack upgrade failed" ;; # --- Default --- *) echo "Unknown error" ;; diff --git a/scripts/core/tools.func b/scripts/core/tools.func index 1c73fd6..aee7b40 100644 --- a/scripts/core/tools.func +++ b/scripts/core/tools.func @@ -192,6 +192,8 @@ install_packages_with_retry() { if [[ $retry -le $max_retries ]]; then msg_warn "Package installation failed, retrying ($retry/$max_retries)..." sleep 2 + # Fix any interrupted dpkg operations before retry + $STD dpkg --configure -a 2>/dev/null || true $STD apt update 2>/dev/null || true fi done @@ -217,6 +219,8 @@ upgrade_packages_with_retry() { if [[ $retry -le $max_retries ]]; then msg_warn "Package upgrade failed, retrying ($retry/$max_retries)..." sleep 2 + # Fix any interrupted dpkg operations before retry + $STD dpkg --configure -a 2>/dev/null || true $STD apt update 2>/dev/null || true fi done @@ -1182,6 +1186,11 @@ cleanup_orphaned_sources() { # This should be called at the start of any setup function # ------------------------------------------------------------------------------ ensure_apt_working() { + # Fix interrupted dpkg operations first + # This can happen if a previous installation was interrupted (e.g., by script error) + if [[ -f /var/lib/dpkg/lock-frontend ]] || dpkg --audit 2>&1 | grep -q "interrupted"; then + $STD dpkg --configure -a 2>/dev/null || true + fi # Clean up orphaned sources first cleanup_orphaned_sources @@ -2944,12 +2953,12 @@ setup_mariadb() { # Resolve "latest" to actual version if [[ "$MARIADB_VERSION" == "latest" ]]; then if ! curl -fsI --max-time 10 http://mirror.mariadb.org/repo/ >/dev/null 2>&1; then - msg_warn "MariaDB mirror not reachable - trying mariadb_repo_setup fallback" + msg_warn "MariaDB mirror not reachable - trying mariadb_repo_setup fallback" # Try using official mariadb_repo_setup script as fallback if curl -fsSL --max-time 15 https://r.mariadb.com/downloads/mariadb_repo_setup 2>/dev/null | bash -s -- --skip-verify >/dev/null 2>&1; then msg_ok "MariaDB repository configured via mariadb_repo_setup" # Extract version from configured repo - MARIADB_VERSION=$(grep -oP 'repo/\K[0-9]+\.[0-9]+\.[0-9]+' /etc/apt/sources.list.d/mariadb.list 2>/dev/null | head -n1 || echo "12.2") + MARIADB_VERSION=$(grep -oP 'repo/\K[0-9]+\.[0-9]+\.[0-9]+' /etc/apt/sources.list.d/mariadb.list 2>/dev/null | head -n1 || echo "12.2")Expand commentComment on line R2948ResolvedCode has comments. Press enter to view. else msg_warn "mariadb_repo_setup failed - using hardcoded fallback version" MARIADB_VERSION="12.2" @@ -2963,7 +2972,7 @@ setup_mariadb() { head -n1 || echo "") if [[ -z "$MARIADB_VERSION" ]]; then - msg_warn "Could not parse latest GA MariaDB version from mirror - trying mariadb_repo_setup" + msg_warn "Could not parse latest GA MariaDB version from mirror - trying mariadb_repo_setup" if curl -fsSL --max-time 15 https://r.mariadb.com/downloads/mariadb_repo_setup 2>/dev/null | bash -s -- --skip-verify >/dev/null 2>&1; then msg_ok "MariaDB repository configured via mariadb_repo_setup" MARIADB_VERSION=$(grep -oP 'repo/\K[0-9]+\.[0-9]+\.[0-9]+' /etc/apt/sources.list.d/mariadb.list 2>/dev/null | head -n1 || echo "12.2")