diff --git a/misc/api.func b/misc/api.func index c3bdb4f7c..057ed0339 100644 --- a/misc/api.func +++ b/misc/api.func @@ -48,82 +48,82 @@ # - Shared function with error_handler.func for consistency # ------------------------------------------------------------------------------ explain_exit_code() { - local code="$1" - case "$code" in - # --- Generic / Shell --- - 1) echo "General error / Operation not permitted" ;; - 2) echo "Misuse of shell builtins (e.g. syntax error)" ;; - 126) echo "Command invoked cannot execute (permission problem?)" ;; - 127) echo "Command not found" ;; - 128) echo "Invalid argument to exit" ;; - 130) echo "Terminated by Ctrl+C (SIGINT)" ;; - 137) echo "Killed (SIGKILL / Out of memory?)" ;; - 139) echo "Segmentation fault (core dumped)" ;; - 143) echo "Terminated (SIGTERM)" ;; + local code="$1" + case "$code" in + # --- Generic / Shell --- + 1) echo "General error / Operation not permitted" ;; + 2) echo "Misuse of shell builtins (e.g. syntax error)" ;; + 126) echo "Command invoked cannot execute (permission problem?)" ;; + 127) echo "Command not found" ;; + 128) echo "Invalid argument to exit" ;; + 130) echo "Terminated by Ctrl+C (SIGINT)" ;; + 137) echo "Killed (SIGKILL / Out of memory?)" ;; + 139) echo "Segmentation fault (core dumped)" ;; + 143) echo "Terminated (SIGTERM)" ;; - # --- Package manager / APT / DPKG --- - 100) echo "APT: Package manager error (broken packages / dependency problems)" ;; - 101) echo "APT: Configuration error (bad sources.list, malformed config)" ;; - 255) echo "DPKG: Fatal internal error" ;; + # --- Package manager / APT / DPKG --- + 100) echo "APT: Package manager error (broken packages / dependency problems)" ;; + 101) echo "APT: Configuration error (bad sources.list, malformed config)" ;; + 255) echo "DPKG: Fatal internal error" ;; - # --- Node.js / npm / pnpm / yarn --- - 243) echo "Node.js: Out of memory (JavaScript heap out of memory)" ;; - 245) echo "Node.js: Invalid command-line option" ;; - 246) echo "Node.js: Internal JavaScript Parse Error" ;; - 247) echo "Node.js: Fatal internal error" ;; - 248) echo "Node.js: Invalid C++ addon / N-API failure" ;; - 249) echo "Node.js: Inspector error" ;; - 254) echo "npm/pnpm/yarn: Unknown fatal error" ;; + # --- Node.js / npm / pnpm / yarn --- + 243) echo "Node.js: Out of memory (JavaScript heap out of memory)" ;; + 245) echo "Node.js: Invalid command-line option" ;; + 246) echo "Node.js: Internal JavaScript Parse Error" ;; + 247) echo "Node.js: Fatal internal error" ;; + 248) echo "Node.js: Invalid C++ addon / N-API failure" ;; + 249) echo "Node.js: Inspector error" ;; + 254) echo "npm/pnpm/yarn: Unknown fatal error" ;; - # --- Python / pip / uv --- - 210) echo "Python: Virtualenv / uv environment missing or broken" ;; - 211) echo "Python: Dependency resolution failed" ;; - 212) echo "Python: Installation aborted (permissions or EXTERNALLY-MANAGED)" ;; + # --- Python / pip / uv --- + 210) echo "Python: Virtualenv / uv environment missing or broken" ;; + 211) echo "Python: Dependency resolution failed" ;; + 212) echo "Python: Installation aborted (permissions or EXTERNALLY-MANAGED)" ;; - # --- PostgreSQL --- - 231) echo "PostgreSQL: Connection failed (server not running / wrong socket)" ;; - 232) echo "PostgreSQL: Authentication failed (bad user/password)" ;; - 233) echo "PostgreSQL: Database does not exist" ;; - 234) echo "PostgreSQL: Fatal error in query / syntax" ;; + # --- PostgreSQL --- + 231) echo "PostgreSQL: Connection failed (server not running / wrong socket)" ;; + 232) echo "PostgreSQL: Authentication failed (bad user/password)" ;; + 233) echo "PostgreSQL: Database does not exist" ;; + 234) echo "PostgreSQL: Fatal error in query / syntax" ;; - # --- MySQL / MariaDB --- - 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" ;; + # --- MySQL / MariaDB --- + 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" ;; + # --- 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" ;; - 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)" ;; - 210) echo "Custom: Cluster not quorate" ;; - 211) echo "Custom: Timeout waiting for template lock (concurrent download in progress)" ;; - 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')" ;; - 231) echo "Custom: LXC stack upgrade/retry failed (outdated pve-container - check https://github.com/community-scripts/ProxmoxVE/discussions/8126)" ;; + # --- Proxmox Custom Codes --- + 200) echo "Custom: Failed to create lock file" ;; + 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)" ;; + 210) echo "Custom: Cluster not quorate" ;; + 211) echo "Custom: Timeout waiting for template lock (concurrent download in progress)" ;; + 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')" ;; + 231) echo "Custom: LXC stack upgrade/retry failed (outdated pve-container - check https://github.com/community-scripts/ProxmoxVE/discussions/8126)" ;; - # --- Default --- - *) echo "Unknown error" ;; - esac + # --- Default --- + *) echo "Unknown error" ;; + esac } # ============================================================================== @@ -151,26 +151,26 @@ explain_exit_code() { # ------------------------------------------------------------------------------ post_to_api() { - echo "post_to_api" + echo "post_to_api" - if ! command -v curl &>/dev/null; then - return - fi + if ! command -v curl &>/dev/null; then + return + fi - if [ "$DIAGNOSTICS" = "no" ]; then - return - fi + if [ "$DIAGNOSTICS" = "no" ]; then + return + fi - if [ -z "$RANDOM_UUID" ]; then - return - fi + if [ -z "$RANDOM_UUID" ]; then + return + fi - local API_URL="http://api.community-scripts.org/dev/upload" - local pve_version="not found" - pve_version=$(pveversion | awk -F'[/ ]' '{print $2}') + local API_URL="http://api.community-scripts.org/dev/upload" + local pve_version="not found" + pve_version=$(pveversion | awk -F'[/ ]' '{print $2}') - JSON_PAYLOAD=$( - cat </dev/null; then - return - fi + if ! command -v curl &>/dev/null; then + return + fi - # Initialize flag if not set (prevents 'unbound variable' error with set -u) - POST_UPDATE_DONE=${POST_UPDATE_DONE:-false} + # Initialize flag if not set (prevents 'unbound variable' error with set -u) + POST_UPDATE_DONE=${POST_UPDATE_DONE:-false} - if [ "$POST_UPDATE_DONE" = true ]; then - return 0 - fi - exit_code=${2:-1} - local API_URL="http://api.community-scripts.org/dev/upload/updatestatus" - local status="${1:-failed}" - if [[ "$status" == "failed" ]]; then - local exit_code="${2:-1}" - elif [[ "$status" == "success" ]]; then - local exit_code="${2:-0}" - fi + if [ "$POST_UPDATE_DONE" = true ]; then + return 0 + fi + exit_code=${2:-1} + local API_URL="http://api.community-scripts.org/dev/upload/updatestatus" + local status="${1:-failed}" + if [[ "$status" == "failed" ]]; then + local exit_code="${2:-1}" + elif [[ "$status" == "success" ]]; then + local exit_code="${2:-0}" + fi - if [[ -z "$exit_code" ]]; then - exit_code=1 - fi + if [[ -z "$exit_code" ]]; then + exit_code=1 + fi - error=$(explain_exit_code "$exit_code") + error=$(explain_exit_code "$exit_code") - if [ -z "$error" ]; then - error="Unknown error" - fi + if [ -z "$error" ]; then + error="Unknown error" + fi - JSON_PAYLOAD=$( - cat </dev/null 2>&1 && motd_ssh || true - " >/dev/null 2>&1; then - msg_dev "MOTD/SSH ready - container accessible via SSH (IP: $ip_in_lxc)" - else - msg_warn "MOTD/SSH setup failed, but continuing with installation" - fi - fi - # Run application installer # NOTE: We disable error handling here because: # 1. Container errors are caught by error_handler INSIDE container @@ -2850,6 +2835,18 @@ EOF' echo -e "${BFR}${CM}${GN}Container ${CTID} removed${CL}" elif [[ "$response" =~ ^[Nn]$ ]]; then echo -e "\n${TAB}${YW}Container ${CTID} kept for debugging${CL}" + + # Dev mode: Setup MOTD/SSH for debugging access to broken container + if [[ "${DEV_MODE_MOTD:-false}" == "true" ]]; then + echo -e "${TAB}${HOLD}${DGN}Setting up MOTD and SSH for debugging...${CL}" + if pct exec "$CTID" -- bash -c " + source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/install.func) + declare -f motd_ssh >/dev/null 2>&1 && motd_ssh || true + " >/dev/null 2>&1; then + local 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}" + fi + fi fi else # Timeout - auto-remove @@ -3760,6 +3757,17 @@ create_lxc_container() { # - Posts final "done" status to API telemetry # ------------------------------------------------------------------------------ description() { + # Dev mode: Setup MOTD/SSH on successful installation + if [[ "${DEV_MODE_MOTD:-false}" == "true" ]]; then + msg_dev "Setting up MOTD and SSH for debugging access" + if pct exec "$CTID" -- bash -c " + source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/install.func) + declare -f motd_ssh >/dev/null 2>&1 && motd_ssh || true + " >/dev/null 2>&1; then + msg_dev "MOTD/SSH configured successfully" + fi + fi + IP=$(pct exec "$CTID" ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) # Generate LXC Description diff --git a/misc/core.func b/misc/core.func index 658e6580c..0fdd2c58c 100644 --- a/misc/core.func +++ b/misc/core.func @@ -834,8 +834,9 @@ cleanup_lxc() { if command -v composer &>/dev/null; then $STD composer clear-cache || true; fi if command -v journalctl &>/dev/null; then - $STD journalctl --rotate || true - $STD journalctl --vacuum-time=10m || true + # Journal rotation may fail if systemd-journald not fully initialized yet + journalctl --rotate 2>/dev/null || true + journalctl --vacuum-time=10m 2>/dev/null || true fi msg_ok "Cleaned" }