mirror of
https://github.com/community-scripts/ProxmoxVED.git
synced 2026-02-25 05:57:26 +00:00
Replace Go API with PocketBase; update docs
Remove the old Go/Mongo API (api/main.go, go.mod, go.sum, .env.example) and switch telemetry backend to PocketBase (http://db.community-scripts.org). Update documentation and flowcharts to reflect the PocketBase collection (_dev_telemetry_data), new REST endpoints (POST/PATCH/GET), field schema, and revised api.func integration (LXC/VM reporting and status updates). Misc scripts and helpers were adjusted (misc/api.func, misc/build.func, misc/error_handler.func) and a new misc/ingest.go was added. This consolidates telemetry to a hosted PocketBase instance and updates docs and integration points accordingly.
This commit is contained in:
@@ -2,63 +2,88 @@
|
||||
|
||||
## Overview
|
||||
|
||||
This document provides a comprehensive alphabetical reference of all functions in `api.func`, including parameters, dependencies, usage examples, and error handling.
|
||||
This document provides a comprehensive reference of all functions in `api.func`, including parameters, dependencies, usage examples, and error handling. The backend is **PocketBase** hosted at `http://db.community-scripts.org`.
|
||||
|
||||
## Configuration Variables
|
||||
|
||||
| Variable | Value | Description |
|
||||
|----------|-------|-------------|
|
||||
| `PB_URL` | `http://db.community-scripts.org` | PocketBase server URL |
|
||||
| `PB_COLLECTION` | `_dev_telemetry_data` | PocketBase collection name |
|
||||
| `PB_API_URL` | `${PB_URL}/api/collections/${PB_COLLECTION}/records` | Full API endpoint |
|
||||
| `PB_RECORD_ID` | *(runtime)* | Stores the PocketBase record ID returned by POST for later PATCH calls |
|
||||
|
||||
## Function Categories
|
||||
|
||||
### Error Description Functions
|
||||
|
||||
#### `get_error_description()`
|
||||
#### `explain_exit_code()`
|
||||
|
||||
**Purpose**: Convert numeric exit codes to human-readable explanations
|
||||
**Parameters**:
|
||||
- `$1` - Exit code to explain
|
||||
- `$1` — Exit code to explain
|
||||
**Returns**: Human-readable error explanation string
|
||||
**Side Effects**: None
|
||||
**Dependencies**: None
|
||||
**Environment Variables Used**: None
|
||||
|
||||
**Supported Exit Codes**:
|
||||
- **General System**: 0-9, 18, 22, 28, 35, 56, 60, 125-128, 129-143, 152, 255
|
||||
- **LXC-Specific**: 100-101, 200-209
|
||||
- **Docker**: 125
|
||||
> **Note**: `explain_exit_code()` is the **canonical** function for exit-code mapping. It is used by both `api.func` (telemetry) and `error_handler.func` (error display).
|
||||
|
||||
**Supported Exit Code Ranges** (non-overlapping):
|
||||
|
||||
| Range | Category |
|
||||
|-------|----------|
|
||||
| 1–2 | Generic / Shell |
|
||||
| 6–35 | curl / wget |
|
||||
| 100–102 | APT / Package manager |
|
||||
| 124–143 | System / Signals |
|
||||
| 150–154 | Systemd / Service |
|
||||
| 160–162 | Python / pip / uv |
|
||||
| 170–173 | PostgreSQL |
|
||||
| 180–183 | MySQL / MariaDB |
|
||||
| 190–193 | MongoDB |
|
||||
| 200–231 | Proxmox custom codes |
|
||||
| 243–249 | Node.js / npm |
|
||||
| 255 | DPKG fatal |
|
||||
|
||||
**Usage Example**:
|
||||
```bash
|
||||
error_msg=$(get_error_description 127)
|
||||
error_msg=$(explain_exit_code 127)
|
||||
echo "Error 127: $error_msg"
|
||||
# Output: Error 127: Command not found: Incorrect path or missing dependency.
|
||||
# Output: Error 127: Command not found
|
||||
```
|
||||
|
||||
**Error Code Examples**:
|
||||
```bash
|
||||
get_error_description 0 # " " (space)
|
||||
get_error_description 1 # "General error: An unspecified error occurred."
|
||||
get_error_description 127 # "Command not found: Incorrect path or missing dependency."
|
||||
get_error_description 200 # "LXC creation failed."
|
||||
get_error_description 255 # "Unknown critical error, often due to missing permissions or broken scripts."
|
||||
explain_exit_code 1 # "General error / Operation not permitted"
|
||||
explain_exit_code 22 # "curl: HTTP error returned (404, 429, 500+)"
|
||||
explain_exit_code 127 # "Command not found"
|
||||
explain_exit_code 200 # "Proxmox: Failed to create lock file"
|
||||
explain_exit_code 255 # "DPKG: Fatal internal error"
|
||||
explain_exit_code 999 # "Unknown error"
|
||||
```
|
||||
|
||||
### API Communication Functions
|
||||
|
||||
#### `post_to_api()`
|
||||
**Purpose**: Send LXC container installation data to community-scripts.org API
|
||||
|
||||
**Purpose**: Create an LXC container telemetry record in PocketBase
|
||||
**Parameters**: None (uses environment variables)
|
||||
**Returns**: None
|
||||
**Side Effects**:
|
||||
- Sends HTTP POST request to API
|
||||
- Stores response in RESPONSE variable
|
||||
- Requires curl command and network connectivity
|
||||
- Sends HTTP **POST** to `PB_API_URL`
|
||||
- Stores the returned PocketBase record `id` in `PB_RECORD_ID` for later PATCH updates
|
||||
**Dependencies**: `curl` command
|
||||
**Environment Variables Used**: `DIAGNOSTICS`, `RANDOM_UUID`, `CT_TYPE`, `DISK_SIZE`, `CORE_COUNT`, `RAM_SIZE`, `var_os`, `var_version`, `DISABLEIP6`, `NSAPP`, `METHOD`
|
||||
**Environment Variables Used**: `DIAGNOSTICS`, `RANDOM_UUID`, `CT_TYPE`, `DISK_SIZE`, `CORE_COUNT`, `RAM_SIZE`, `var_os`, `var_version`, `NSAPP`, `METHOD`
|
||||
|
||||
**Prerequisites**:
|
||||
- `curl` command must be available
|
||||
- `DIAGNOSTICS` must be set to "yes"
|
||||
- `curl` must be available
|
||||
- `DIAGNOSTICS` must be `"yes"`
|
||||
- `RANDOM_UUID` must be set and not empty
|
||||
|
||||
**API Endpoint**: `http://api.community-scripts.org/dev/upload`
|
||||
**API Endpoint**: `POST http://db.community-scripts.org/api/collections/_dev_telemetry_data/records`
|
||||
|
||||
**JSON Payload Structure**:
|
||||
**JSON Payload**:
|
||||
```json
|
||||
{
|
||||
"ct_type": 1,
|
||||
@@ -68,7 +93,6 @@ get_error_description 255 # "Unknown critical error, often due to missing perm
|
||||
"ram_size": 2048,
|
||||
"os_type": "debian",
|
||||
"os_version": "12",
|
||||
"disableip6": "true",
|
||||
"nsapp": "plex",
|
||||
"method": "install",
|
||||
"pve_version": "8.0",
|
||||
@@ -77,6 +101,10 @@ get_error_description 255 # "Unknown critical error, often due to missing perm
|
||||
}
|
||||
```
|
||||
|
||||
**Response Handling**:
|
||||
- On HTTP 200/201, `PB_RECORD_ID` is extracted from the response JSON (`"id"` field)
|
||||
- On failure, the function returns silently without blocking the installation
|
||||
|
||||
**Usage Example**:
|
||||
```bash
|
||||
export DIAGNOSTICS="yes"
|
||||
@@ -91,39 +119,39 @@ export NSAPP="plex"
|
||||
export METHOD="install"
|
||||
|
||||
post_to_api
|
||||
# PB_RECORD_ID is now set (e.g. "abc123def456789")
|
||||
```
|
||||
|
||||
#### `post_to_api_vm()`
|
||||
**Purpose**: Send VM installation data to community-scripts.org API
|
||||
|
||||
**Purpose**: Create a VM telemetry record in PocketBase
|
||||
**Parameters**: None (uses environment variables)
|
||||
**Returns**: None
|
||||
**Side Effects**:
|
||||
- Sends HTTP POST request to API
|
||||
- Stores response in RESPONSE variable
|
||||
- Requires curl command and network connectivity
|
||||
- Sends HTTP **POST** to `PB_API_URL`
|
||||
- Stores the returned PocketBase record `id` in `PB_RECORD_ID`
|
||||
**Dependencies**: `curl` command, diagnostics file
|
||||
**Environment Variables Used**: `DIAGNOSTICS`, `RANDOM_UUID`, `DISK_SIZE`, `CORE_COUNT`, `RAM_SIZE`, `var_os`, `var_version`, `NSAPP`, `METHOD`
|
||||
**Environment Variables Used**: `RANDOM_UUID`, `DISK_SIZE`, `CORE_COUNT`, `RAM_SIZE`, `var_os`, `var_version`, `NSAPP`, `METHOD`
|
||||
|
||||
**Prerequisites**:
|
||||
- `/usr/local/community-scripts/diagnostics` file must exist
|
||||
- `DIAGNOSTICS` must be set to "yes" in diagnostics file
|
||||
- `curl` command must be available
|
||||
- `DIAGNOSTICS` must be `"yes"` in that file (read at runtime)
|
||||
- `curl` must be available
|
||||
- `RANDOM_UUID` must be set and not empty
|
||||
|
||||
**API Endpoint**: `http://api.community-scripts.org/dev/upload`
|
||||
**API Endpoint**: `POST http://db.community-scripts.org/api/collections/_dev_telemetry_data/records`
|
||||
|
||||
**JSON Payload Structure**:
|
||||
**JSON Payload**:
|
||||
```json
|
||||
{
|
||||
"ct_type": 2,
|
||||
"type": "vm",
|
||||
"disk_size": 8,
|
||||
"core_count": 2,
|
||||
"ram_size": 2048,
|
||||
"os_type": "debian",
|
||||
"os_version": "12",
|
||||
"disableip6": "",
|
||||
"nsapp": "plex",
|
||||
"disk_size": 20,
|
||||
"core_count": 4,
|
||||
"ram_size": 4096,
|
||||
"os_type": "ubuntu",
|
||||
"os_version": "22.04",
|
||||
"nsapp": "nextcloud",
|
||||
"method": "install",
|
||||
"pve_version": "8.0",
|
||||
"status": "installing",
|
||||
@@ -131,50 +159,81 @@ post_to_api
|
||||
}
|
||||
```
|
||||
|
||||
> **Note**: `DISK_SIZE` is stripped of its `G` suffix before sending (e.g. `"20G"` → `20`).
|
||||
|
||||
**Usage Example**:
|
||||
```bash
|
||||
# Create diagnostics file
|
||||
mkdir -p /usr/local/community-scripts
|
||||
echo "DIAGNOSTICS=yes" > /usr/local/community-scripts/diagnostics
|
||||
|
||||
export RANDOM_UUID="$(uuidgen)"
|
||||
export DISK_SIZE="8G"
|
||||
export CORE_COUNT=2
|
||||
export RAM_SIZE=2048
|
||||
export var_os="debian"
|
||||
export var_version="12"
|
||||
export NSAPP="plex"
|
||||
export DISK_SIZE="20G"
|
||||
export CORE_COUNT=4
|
||||
export RAM_SIZE=4096
|
||||
export var_os="ubuntu"
|
||||
export var_version="22.04"
|
||||
export NSAPP="nextcloud"
|
||||
export METHOD="install"
|
||||
|
||||
post_to_api_vm
|
||||
# PB_RECORD_ID is now set
|
||||
```
|
||||
|
||||
#### `post_update_to_api()`
|
||||
**Purpose**: Send installation completion status to community-scripts.org API
|
||||
|
||||
**Purpose**: Update an existing PocketBase record with installation completion status via PATCH
|
||||
**Parameters**:
|
||||
- `$1` - Status ("success" or "failed", default: "failed")
|
||||
- `$2` - Exit code (default: 1)
|
||||
- `$1` — Status (`"done"`, `"success"`, or `"failed"`; default: `"failed"`)
|
||||
- `$2` — Exit code (numeric, default: `1`)
|
||||
**Returns**: None
|
||||
**Side Effects**:
|
||||
- Sends HTTP POST request to API
|
||||
- Sets POST_UPDATE_DONE=true to prevent duplicates
|
||||
- Stores response in RESPONSE variable
|
||||
**Dependencies**: `curl` command, `get_error_description()`
|
||||
**Environment Variables Used**: `DIAGNOSTICS`, `RANDOM_UUID`
|
||||
- Sends HTTP **PATCH** to `PB_API_URL/{record_id}`
|
||||
- Sets `POST_UPDATE_DONE=true` to prevent duplicate calls
|
||||
**Dependencies**: `curl`, `explain_exit_code()`
|
||||
**Environment Variables Used**: `DIAGNOSTICS`, `RANDOM_UUID`, `PB_RECORD_ID`
|
||||
|
||||
**Prerequisites**:
|
||||
- `curl` command must be available
|
||||
- `DIAGNOSTICS` must be set to "yes"
|
||||
- `curl` must be available
|
||||
- `DIAGNOSTICS` must be `"yes"`
|
||||
- `RANDOM_UUID` must be set and not empty
|
||||
- POST_UPDATE_DONE must be false (prevents duplicates)
|
||||
- `POST_UPDATE_DONE` must not be `"true"` (prevents duplicate updates)
|
||||
|
||||
**API Endpoint**: `http://api.community-scripts.org/dev/upload/updatestatus`
|
||||
**Record Lookup**:
|
||||
1. If `PB_RECORD_ID` is already set (from a prior `post_to_api` / `post_to_api_vm` call), it is used directly.
|
||||
2. Otherwise, the function performs a **GET** lookup:
|
||||
```
|
||||
GET PB_API_URL?filter=(random_id='<RANDOM_UUID>')&fields=id&perPage=1
|
||||
```
|
||||
3. If no record is found, the function sets `POST_UPDATE_DONE=true` and returns.
|
||||
|
||||
**JSON Payload Structure**:
|
||||
**Status Mapping** (PocketBase select field values: `installing`, `sucess`, `failed`, `unknown`):
|
||||
|
||||
| Input Status | PocketBase `status` | `exit_code` | `error` |
|
||||
|---|---|---|---|
|
||||
| `"done"` / `"success"` / `"sucess"` | `"sucess"` | `0` | `""` |
|
||||
| `"failed"` | `"failed"` | *from $2* | *from `explain_exit_code()`* |
|
||||
| anything else | `"unknown"` | *from $2* | *from `explain_exit_code()`* |
|
||||
|
||||
> **Note**: The PocketBase schema intentionally spells success as `"sucess"`.
|
||||
|
||||
**API Endpoint**: `PATCH http://db.community-scripts.org/api/collections/_dev_telemetry_data/records/{record_id}`
|
||||
|
||||
**JSON Payload**:
|
||||
```json
|
||||
{
|
||||
"status": "success",
|
||||
"error": "Error description from get_error_description()",
|
||||
"random_id": "uuid-string"
|
||||
"status": "sucess",
|
||||
"error": "",
|
||||
"exit_code": 0
|
||||
}
|
||||
```
|
||||
|
||||
or for failures:
|
||||
```json
|
||||
{
|
||||
"status": "failed",
|
||||
"error": "Command not found",
|
||||
"exit_code": 127
|
||||
}
|
||||
```
|
||||
|
||||
@@ -183,10 +242,10 @@ post_to_api_vm
|
||||
export DIAGNOSTICS="yes"
|
||||
export RANDOM_UUID="$(uuidgen)"
|
||||
|
||||
# Report successful installation
|
||||
post_update_to_api "success" 0
|
||||
# After a successful installation
|
||||
post_update_to_api "done" 0
|
||||
|
||||
# Report failed installation
|
||||
# After a failed installation
|
||||
post_update_to_api "failed" 127
|
||||
```
|
||||
|
||||
@@ -196,198 +255,250 @@ post_update_to_api "failed" 127
|
||||
```
|
||||
post_to_api()
|
||||
├── Check curl availability
|
||||
├── Check DIAGNOSTICS setting
|
||||
├── Check RANDOM_UUID
|
||||
├── Check DIAGNOSTICS == "yes"
|
||||
├── Check RANDOM_UUID is set
|
||||
├── Get PVE version
|
||||
├── Create JSON payload
|
||||
└── Send HTTP POST request
|
||||
├── Create JSON payload (ct_type=1, type="lxc", status="installing")
|
||||
├── POST to PB_API_URL
|
||||
└── Extract PB_RECORD_ID from response
|
||||
|
||||
post_to_api_vm()
|
||||
├── Check diagnostics file
|
||||
├── Read DIAGNOSTICS from /usr/local/community-scripts/diagnostics
|
||||
├── Check curl availability
|
||||
├── Check DIAGNOSTICS setting
|
||||
├── Check RANDOM_UUID
|
||||
├── Process disk size
|
||||
├── Check DIAGNOSTICS == "yes"
|
||||
├── Check RANDOM_UUID is set
|
||||
├── Strip 'G' suffix from DISK_SIZE
|
||||
├── Get PVE version
|
||||
├── Create JSON payload
|
||||
└── Send HTTP POST request
|
||||
├── Create JSON payload (ct_type=2, type="vm", status="installing")
|
||||
├── POST to PB_API_URL
|
||||
└── Extract PB_RECORD_ID from response
|
||||
|
||||
post_update_to_api()
|
||||
├── Check POST_UPDATE_DONE flag
|
||||
post_update_to_api(status, exit_code)
|
||||
├── Check curl availability
|
||||
├── Check DIAGNOSTICS setting
|
||||
├── Check RANDOM_UUID
|
||||
├── Determine status and exit code
|
||||
├── Get error description
|
||||
├── Create JSON payload
|
||||
├── Send HTTP POST request
|
||||
├── Check POST_UPDATE_DONE flag
|
||||
├── Check DIAGNOSTICS == "yes"
|
||||
├── Check RANDOM_UUID is set
|
||||
├── Map status → pb_status ("done"→"sucess", "failed"→"failed", *→"unknown")
|
||||
├── For failed/unknown: call explain_exit_code(exit_code)
|
||||
├── Resolve record_id (PB_RECORD_ID or GET lookup by random_id)
|
||||
├── PATCH to PB_API_URL/{record_id}
|
||||
└── Set POST_UPDATE_DONE=true
|
||||
```
|
||||
|
||||
### Error Description Flow
|
||||
```
|
||||
get_error_description()
|
||||
├── Match exit code
|
||||
├── Return appropriate description
|
||||
└── Handle unknown codes
|
||||
explain_exit_code(code)
|
||||
├── Match code against case statement (non-overlapping ranges)
|
||||
├── Return description string
|
||||
└── Default: "Unknown error"
|
||||
```
|
||||
|
||||
## Error Code Reference
|
||||
|
||||
### General System Errors
|
||||
### Generic / Shell (1–2)
|
||||
| Code | Description |
|
||||
|------|-------------|
|
||||
| 0 | (space) |
|
||||
| 1 | General error: An unspecified error occurred. |
|
||||
| 2 | Incorrect shell usage or invalid command arguments. |
|
||||
| 3 | Unexecuted function or invalid shell condition. |
|
||||
| 4 | Error opening a file or invalid path. |
|
||||
| 5 | I/O error: An input/output failure occurred. |
|
||||
| 6 | No such device or address. |
|
||||
| 7 | Insufficient memory or resource exhaustion. |
|
||||
| 8 | Non-executable file or invalid file format. |
|
||||
| 9 | Failed child process execution. |
|
||||
| 18 | Connection to a remote server failed. |
|
||||
| 22 | Invalid argument or faulty network connection. |
|
||||
| 28 | No space left on device. |
|
||||
| 35 | Timeout while establishing a connection. |
|
||||
| 56 | Faulty TLS connection. |
|
||||
| 60 | SSL certificate error. |
|
||||
| 1 | General error / Operation not permitted |
|
||||
| 2 | Misuse of shell builtins (e.g. syntax error) |
|
||||
|
||||
### Command Execution Errors
|
||||
### curl / wget (6–35)
|
||||
| Code | Description |
|
||||
|------|-------------|
|
||||
| 125 | Docker error: Container could not start. |
|
||||
| 126 | Command not executable: Incorrect permissions or missing dependencies. |
|
||||
| 127 | Command not found: Incorrect path or missing dependency. |
|
||||
| 128 | Invalid exit signal, e.g., incorrect Git command. |
|
||||
| 6 | curl: DNS resolution failed (could not resolve host) |
|
||||
| 7 | curl: Failed to connect (network unreachable / host down) |
|
||||
| 22 | curl: HTTP error returned (404, 429, 500+) |
|
||||
| 28 | curl: Operation timeout (network slow or server not responding) |
|
||||
| 35 | curl: SSL/TLS handshake failed (certificate error) |
|
||||
|
||||
### Signal Errors
|
||||
### APT / Package Manager (100–102)
|
||||
| Code | Description |
|
||||
|------|-------------|
|
||||
| 129 | Signal 1 (SIGHUP): Process terminated due to hangup. |
|
||||
| 130 | Signal 2 (SIGINT): Manual termination via Ctrl+C. |
|
||||
| 132 | Signal 4 (SIGILL): Illegal machine instruction. |
|
||||
| 133 | Signal 5 (SIGTRAP): Debugging error or invalid breakpoint signal. |
|
||||
| 134 | Signal 6 (SIGABRT): Program aborted itself. |
|
||||
| 135 | Signal 7 (SIGBUS): Memory error, invalid memory address. |
|
||||
| 137 | Signal 9 (SIGKILL): Process forcibly terminated (OOM-killer or 'kill -9'). |
|
||||
| 139 | Signal 11 (SIGSEGV): Segmentation fault, possibly due to invalid pointer access. |
|
||||
| 141 | Signal 13 (SIGPIPE): Pipe closed unexpectedly. |
|
||||
| 143 | Signal 15 (SIGTERM): Process terminated normally. |
|
||||
| 152 | Signal 24 (SIGXCPU): CPU time limit exceeded. |
|
||||
| 100 | APT: Package manager error (broken packages / dependency problems) |
|
||||
| 101 | APT: Configuration error (bad sources.list, malformed config) |
|
||||
| 102 | APT: Lock held by another process (dpkg/apt still running) |
|
||||
|
||||
### LXC-Specific Errors
|
||||
### System / Signals (124–143)
|
||||
| Code | Description |
|
||||
|------|-------------|
|
||||
| 100 | LXC install error: Unexpected error in create_lxc.sh. |
|
||||
| 101 | LXC install error: No network connection detected. |
|
||||
| 200 | LXC creation failed. |
|
||||
| 201 | LXC error: Invalid Storage class. |
|
||||
| 202 | User aborted menu in create_lxc.sh. |
|
||||
| 203 | CTID not set in create_lxc.sh. |
|
||||
| 204 | PCT_OSTYPE not set in create_lxc.sh. |
|
||||
| 205 | CTID cannot be less than 100 in create_lxc.sh. |
|
||||
| 206 | CTID already in use in create_lxc.sh. |
|
||||
| 207 | Template not found in create_lxc.sh. |
|
||||
| 208 | Error downloading template in create_lxc.sh. |
|
||||
| 209 | Container creation failed, but template is intact in create_lxc.sh. |
|
||||
| 124 | Command timed out (timeout command) |
|
||||
| 126 | Command invoked cannot execute (permission problem?) |
|
||||
| 127 | Command not found |
|
||||
| 128 | Invalid argument to exit |
|
||||
| 130 | Terminated by Ctrl+C (SIGINT) |
|
||||
| 134 | Process aborted (SIGABRT — possibly Node.js heap overflow) |
|
||||
| 137 | Killed (SIGKILL / Out of memory?) |
|
||||
| 139 | Segmentation fault (core dumped) |
|
||||
| 141 | Broken pipe (SIGPIPE — output closed prematurely) |
|
||||
| 143 | Terminated (SIGTERM) |
|
||||
|
||||
### Other Errors
|
||||
### Systemd / Service (150–154)
|
||||
| Code | Description |
|
||||
|------|-------------|
|
||||
| 255 | Unknown critical error, often due to missing permissions or broken scripts. |
|
||||
| * | Unknown error code (exit_code). |
|
||||
| 150 | Systemd: Service failed to start |
|
||||
| 151 | Systemd: Service unit not found |
|
||||
| 152 | Permission denied (EACCES) |
|
||||
| 153 | Build/compile failed (make/gcc/cmake) |
|
||||
| 154 | Node.js: Native addon build failed (node-gyp) |
|
||||
|
||||
### Python / pip / uv (160–162)
|
||||
| Code | Description |
|
||||
|------|-------------|
|
||||
| 160 | Python: Virtualenv / uv environment missing or broken |
|
||||
| 161 | Python: Dependency resolution failed |
|
||||
| 162 | Python: Installation aborted (permissions or EXTERNALLY-MANAGED) |
|
||||
|
||||
### PostgreSQL (170–173)
|
||||
| Code | Description |
|
||||
|------|-------------|
|
||||
| 170 | PostgreSQL: Connection failed (server not running / wrong socket) |
|
||||
| 171 | PostgreSQL: Authentication failed (bad user/password) |
|
||||
| 172 | PostgreSQL: Database does not exist |
|
||||
| 173 | PostgreSQL: Fatal error in query / syntax |
|
||||
|
||||
### MySQL / MariaDB (180–183)
|
||||
| Code | Description |
|
||||
|------|-------------|
|
||||
| 180 | MySQL/MariaDB: Connection failed (server not running / wrong socket) |
|
||||
| 181 | MySQL/MariaDB: Authentication failed (bad user/password) |
|
||||
| 182 | MySQL/MariaDB: Database does not exist |
|
||||
| 183 | MySQL/MariaDB: Fatal error in query / syntax |
|
||||
|
||||
### MongoDB (190–193)
|
||||
| Code | Description |
|
||||
|------|-------------|
|
||||
| 190 | MongoDB: Connection failed (server not running) |
|
||||
| 191 | MongoDB: Authentication failed (bad user/password) |
|
||||
| 192 | MongoDB: Database not found |
|
||||
| 193 | MongoDB: Fatal query error |
|
||||
|
||||
### Proxmox Custom Codes (200–231)
|
||||
| Code | Description |
|
||||
|------|-------------|
|
||||
| 200 | Proxmox: Failed to create lock file |
|
||||
| 203 | Proxmox: Missing CTID variable |
|
||||
| 204 | Proxmox: Missing PCT_OSTYPE variable |
|
||||
| 205 | Proxmox: Invalid CTID (<100) |
|
||||
| 206 | Proxmox: CTID already in use |
|
||||
| 207 | Proxmox: Password contains unescaped special characters |
|
||||
| 208 | Proxmox: Invalid configuration (DNS/MAC/Network format) |
|
||||
| 209 | Proxmox: Container creation failed |
|
||||
| 210 | Proxmox: Cluster not quorate |
|
||||
| 211 | Proxmox: Timeout waiting for template lock |
|
||||
| 212 | Proxmox: Storage type 'iscsidirect' does not support containers (VMs only) |
|
||||
| 213 | Proxmox: Storage type does not support 'rootdir' content |
|
||||
| 214 | Proxmox: Not enough storage space |
|
||||
| 215 | Proxmox: Container created but not listed (ghost state) |
|
||||
| 216 | Proxmox: RootFS entry missing in config |
|
||||
| 217 | Proxmox: Storage not accessible |
|
||||
| 218 | Proxmox: Template file corrupted or incomplete |
|
||||
| 219 | Proxmox: CephFS does not support containers — use RBD |
|
||||
| 220 | Proxmox: Unable to resolve template path |
|
||||
| 221 | Proxmox: Template file not readable |
|
||||
| 222 | Proxmox: Template download failed |
|
||||
| 223 | Proxmox: Template not available after download |
|
||||
| 224 | Proxmox: PBS storage is for backups only |
|
||||
| 225 | Proxmox: No template available for OS/Version |
|
||||
| 231 | Proxmox: LXC stack upgrade failed |
|
||||
|
||||
### Node.js / npm (243–249)
|
||||
| Code | Description |
|
||||
|------|-------------|
|
||||
| 243 | Node.js: Out of memory (JavaScript heap out of memory) |
|
||||
| 245 | Node.js: Invalid command-line option |
|
||||
| 246 | Node.js: Internal JavaScript Parse Error |
|
||||
| 247 | Node.js: Fatal internal error |
|
||||
| 248 | Node.js: Invalid C++ addon / N-API failure |
|
||||
| 249 | npm/pnpm/yarn: Unknown fatal error |
|
||||
|
||||
### DPKG (255)
|
||||
| Code | Description |
|
||||
|------|-------------|
|
||||
| 255 | DPKG: Fatal internal error |
|
||||
|
||||
### Default
|
||||
| Code | Description |
|
||||
|------|-------------|
|
||||
| * | Unknown error |
|
||||
|
||||
## Environment Variable Dependencies
|
||||
|
||||
### Required Variables
|
||||
- **`DIAGNOSTICS`**: Enable/disable diagnostic reporting ("yes"/"no")
|
||||
- **`RANDOM_UUID`**: Unique identifier for tracking
|
||||
- **`DIAGNOSTICS`**: Enable/disable diagnostic reporting (`"yes"` / `"no"`)
|
||||
- **`RANDOM_UUID`**: Unique identifier for session tracking
|
||||
|
||||
### Optional Variables
|
||||
- **`CT_TYPE`**: Container type (1 for LXC, 2 for VM)
|
||||
- **`DISK_SIZE`**: Disk size in GB (or GB with 'G' suffix for VM)
|
||||
### Container / VM Variables
|
||||
- **`CT_TYPE`**: Container type (`1` for LXC, `2` for VM)
|
||||
- **`DISK_SIZE`**: Disk size in GB (VMs may include `G` suffix)
|
||||
- **`CORE_COUNT`**: Number of CPU cores
|
||||
- **`RAM_SIZE`**: RAM size in MB
|
||||
- **`var_os`**: Operating system type
|
||||
- **`var_version`**: OS version
|
||||
- **`DISABLEIP6`**: IPv6 disable setting
|
||||
- **`NSAPP`**: Namespace application name
|
||||
- **`NSAPP`**: Application name
|
||||
- **`METHOD`**: Installation method
|
||||
|
||||
### Internal Variables
|
||||
- **`POST_UPDATE_DONE`**: Prevents duplicate status updates
|
||||
- **`API_URL`**: Community scripts API endpoint
|
||||
- **`JSON_PAYLOAD`**: API request payload
|
||||
- **`RESPONSE`**: API response
|
||||
- **`DISK_SIZE_API`**: Processed disk size for VM API
|
||||
- **`PB_URL`**: PocketBase server URL
|
||||
- **`PB_COLLECTION`**: PocketBase collection name
|
||||
- **`PB_API_URL`**: Full PocketBase API endpoint
|
||||
- **`PB_RECORD_ID`**: PocketBase record ID (set after POST, used for PATCH)
|
||||
- **`POST_UPDATE_DONE`**: Flag to prevent duplicate status updates
|
||||
- **`JSON_PAYLOAD`**: API request payload (local to each function)
|
||||
- **`RESPONSE`**: API response (local to each function)
|
||||
|
||||
## Error Handling Patterns
|
||||
|
||||
### API Communication Errors
|
||||
- All API functions handle curl failures gracefully
|
||||
- Network errors don't block installation process
|
||||
- Missing prerequisites cause early return
|
||||
- Duplicate updates are prevented
|
||||
- All API functions return silently on failure — network errors never block installation
|
||||
- Missing prerequisites (no curl, diagnostics disabled, no UUID) cause early return
|
||||
- `POST_UPDATE_DONE` flag prevents duplicate PATCH updates
|
||||
- PocketBase record lookup falls back to `GET ?filter=(random_id='...')` if `PB_RECORD_ID` is unset
|
||||
|
||||
### Error Description Errors
|
||||
- Unknown error codes return generic message
|
||||
- All error codes are handled with case statement
|
||||
- Fallback message includes the actual error code
|
||||
|
||||
### Prerequisites Validation
|
||||
- Check curl availability before API calls
|
||||
- Validate DIAGNOSTICS setting
|
||||
- Ensure RANDOM_UUID is set
|
||||
- Check for duplicate updates
|
||||
- Unknown error codes return `"Unknown error"`
|
||||
- All recognized codes are handled via a `case` statement with non-overlapping ranges
|
||||
- The fallback message is generic (no error code is embedded)
|
||||
|
||||
## Integration Examples
|
||||
|
||||
### With build.func
|
||||
### With build.func (LXC)
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
source core.func
|
||||
source api.func
|
||||
source build.func
|
||||
|
||||
# Set up API reporting
|
||||
export DIAGNOSTICS="yes"
|
||||
export RANDOM_UUID="$(uuidgen)"
|
||||
|
||||
# Report installation start
|
||||
# Report LXC installation start → POST creates record
|
||||
post_to_api
|
||||
|
||||
# Container creation...
|
||||
# ... build.func code ...
|
||||
# ... container creation via build.func ...
|
||||
|
||||
# Report completion
|
||||
# Report completion → PATCH updates record
|
||||
if [[ $? -eq 0 ]]; then
|
||||
post_update_to_api "success" 0
|
||||
post_update_to_api "done" 0
|
||||
else
|
||||
post_update_to_api "failed" $?
|
||||
fi
|
||||
```
|
||||
|
||||
### With vm-core.func
|
||||
### With vm-core.func (VM)
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
source core.func
|
||||
source api.func
|
||||
source vm-core.func
|
||||
|
||||
# Set up API reporting
|
||||
export DIAGNOSTICS="yes"
|
||||
export RANDOM_UUID="$(uuidgen)"
|
||||
|
||||
# Report VM installation start
|
||||
# Report VM installation start → POST creates record
|
||||
post_to_api_vm
|
||||
|
||||
# VM creation...
|
||||
# ... vm-core.func code ...
|
||||
# ... VM creation via vm-core.func ...
|
||||
|
||||
# Report completion
|
||||
post_update_to_api "success" 0
|
||||
# Report completion → PATCH updates record
|
||||
post_update_to_api "done" 0
|
||||
```
|
||||
|
||||
### With error_handler.func
|
||||
@@ -397,37 +508,30 @@ source core.func
|
||||
source error_handler.func
|
||||
source api.func
|
||||
|
||||
# Use error descriptions
|
||||
error_code=127
|
||||
error_msg=$(get_error_description $error_code)
|
||||
error_msg=$(explain_exit_code $error_code)
|
||||
echo "Error $error_code: $error_msg"
|
||||
|
||||
# Report error to API
|
||||
# Report error to PocketBase
|
||||
post_update_to_api "failed" $error_code
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
### API Usage
|
||||
1. Always check prerequisites before API calls
|
||||
2. Use unique identifiers for tracking
|
||||
3. Handle API failures gracefully
|
||||
4. Don't block installation on API failures
|
||||
1. Always check prerequisites before API calls (handled internally by each function)
|
||||
2. Call `post_to_api` / `post_to_api_vm` **once** at installation start to get a `PB_RECORD_ID`
|
||||
3. Call `post_update_to_api` **once** at the end to finalize the record via PATCH
|
||||
4. Never block the installation on API failures
|
||||
|
||||
### Error Reporting
|
||||
1. Use appropriate error codes
|
||||
2. Provide meaningful error descriptions
|
||||
3. Report both success and failure cases
|
||||
4. Prevent duplicate status updates
|
||||
1. Use `explain_exit_code()` for human-readable error messages
|
||||
2. Pass the actual numeric exit code to `post_update_to_api`
|
||||
3. Report both success (`"done"`) and failure (`"failed"`) cases
|
||||
4. The `POST_UPDATE_DONE` flag automatically prevents duplicate updates
|
||||
|
||||
### Diagnostic Reporting
|
||||
1. Respect user privacy settings
|
||||
2. Only send data when diagnostics enabled
|
||||
3. Use anonymous tracking identifiers
|
||||
4. Include relevant system information
|
||||
|
||||
### Error Handling
|
||||
1. Handle unknown error codes gracefully
|
||||
2. Provide fallback error messages
|
||||
3. Include error code in unknown error messages
|
||||
4. Use consistent error message format
|
||||
1. Respect user privacy — only send data when `DIAGNOSTICS="yes"`
|
||||
2. Use anonymous random UUIDs for session tracking (no personal data)
|
||||
3. Include relevant system information (PVE version, OS, app name)
|
||||
4. The diagnostics file at `/usr/local/community-scripts/diagnostics` controls VM reporting
|
||||
|
||||
Reference in New Issue
Block a user