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:
@@ -1,5 +1,9 @@
|
||||
# api.func Execution Flowchart
|
||||
|
||||
## Overview
|
||||
|
||||
This document illustrates the execution flow of `api.func` functions. The backend is **PocketBase** at `http://db.community-scripts.org`, collection `_dev_telemetry_data`.
|
||||
|
||||
## Main API Communication Flow
|
||||
|
||||
```
|
||||
@@ -10,333 +14,321 @@
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ Prerequisites Check │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ Prerequisites Validation │ │
|
||||
│ │ │ │
|
||||
│ │ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────────┐ │ │
|
||||
│ │ │ Check curl │ │ Check │ │ Check │ │ │
|
||||
│ │ │ Availability │ │ Diagnostics │ │ Random UUID │ │ │
|
||||
│ │ │ │ │ Setting │ │ │ │
|
||||
│ │ │ • command -v │ │ • DIAGNOSTICS │ │ • RANDOM_UUID │ │
|
||||
│ │ │ curl │ │ = "yes" │ │ not empty │ │
|
||||
│ │ │ • Return if │ │ • Return if │ │ • Return if │ │
|
||||
│ │ │ not found │ │ disabled │ │ not set │ │
|
||||
│ │ │ │ │ │ │ │ │
|
||||
│ │ └─────────────────┘ └─────────────────┘ └─────────────────────┘ │ │
|
||||
│ └─────────────────────────────────────────────────────────────────────────────┘ │
|
||||
│ Prerequisites Check │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ Prerequisites Validation │ │
|
||||
│ │ │ │
|
||||
│ │ ┌─────────────────┐ ┌─────────────────┐ ┌──────────────────┐ │ │
|
||||
│ │ │ Check curl │ │ Check │ │ Check │ │ │
|
||||
│ │ │ Availability │ │ DIAGNOSTICS │ │ RANDOM_UUID │ │ │
|
||||
│ │ │ │ │ │ │ │ │ │
|
||||
│ │ │ • command -v │ │ • Must be "yes" │ │ • Must not be │ │ │
|
||||
│ │ │ curl │ │ • Return if │ │ empty │ │ │
|
||||
│ │ │ • Return if │ │ "no" or unset │ │ • Return if │ │ │
|
||||
│ │ │ not found │ │ │ │ not set │ │ │
|
||||
│ │ └─────────────────┘ └─────────────────┘ └──────────────────┘ │ │
|
||||
│ └─────────────────────────────────────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ Data Collection │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ System Information Gathering │ │
|
||||
│ │ │ │
|
||||
│ │ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────────┐ │ │
|
||||
│ │ │ Get PVE │ │ Collect │ │ Prepare JSON │ │ │
|
||||
│ │ │ Version │ │ Environment │ │ Payload │ │
|
||||
│ │ │ │ │ Variables │ │ │ │
|
||||
│ │ │ • pveversion │ │ • CT_TYPE │ │ • Create JSON │ │
|
||||
│ │ │ command │ │ • DISK_SIZE │ │ structure │ │
|
||||
│ │ │ • Parse version │ │ • CORE_COUNT │ │ • Include all │ │
|
||||
│ │ │ • Extract │ │ • RAM_SIZE │ │ variables │ │
|
||||
│ │ │ major.minor │ │ • var_os │ │ • Format for API │ │
|
||||
│ │ │ │ │ • var_version │ │ │ │
|
||||
│ │ │ │ │ • NSAPP │ │ │ │
|
||||
│ │ │ │ │ • METHOD │ │ │ │
|
||||
│ │ └─────────────────┘ └─────────────────┘ └─────────────────────┘ │ │
|
||||
│ └─────────────────────────────────────────────────────────────────────────────┘ │
|
||||
│ Data Collection │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ System Information Gathering │ │
|
||||
│ │ │ │
|
||||
│ │ ┌─────────────────┐ ┌─────────────────┐ ┌──────────────────┐ │ │
|
||||
│ │ │ Get PVE │ │ Collect Env │ │ Build JSON │ │ │
|
||||
│ │ │ Version │ │ Variables │ │ Payload │ │ │
|
||||
│ │ │ │ │ │ │ │ │ │
|
||||
│ │ │ • pveversion │ │ • CT_TYPE │ │ • Heredoc JSON │ │ │
|
||||
│ │ │ command │ │ • DISK_SIZE │ │ • Include all │ │ │
|
||||
│ │ │ • Parse version │ │ • CORE_COUNT │ │ fields │ │ │
|
||||
│ │ │ • Fallback: │ │ • RAM_SIZE │ │ • status = │ │ │
|
||||
│ │ │ "not found" │ │ • var_os │ │ "installing" │ │ │
|
||||
│ │ │ │ │ • NSAPP, METHOD │ │ │ │ │
|
||||
│ │ └─────────────────┘ └─────────────────┘ └──────────────────┘ │ │
|
||||
│ └─────────────────────────────────────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ API Request Execution │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ HTTP Request Processing │ │
|
||||
│ │ │ │
|
||||
│ │ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────────┐ │ │
|
||||
│ │ │ Prepare │ │ Execute │ │ Handle │ │ │
|
||||
│ │ │ Request │ │ HTTP Request │ │ Response │ │
|
||||
│ │ │ │ │ │ │ │ │
|
||||
│ │ │ • Set API URL │ │ • curl -s -w │ │ • Capture HTTP │ │
|
||||
│ │ │ • Set headers │ │ "%{http_code}" │ │ status code │ │
|
||||
│ │ │ • Set payload │ │ • POST request │ │ • Store response │ │
|
||||
│ │ │ • Content-Type │ │ • JSON data │ │ • Handle errors │ │
|
||||
│ │ │ application/ │ │ • Follow │ │ gracefully │ │
|
||||
│ │ │ json │ │ redirects │ │ │ │
|
||||
│ │ └─────────────────┘ └─────────────────┘ └─────────────────────┘ │ │
|
||||
│ └─────────────────────────────────────────────────────────────────────────────┘ │
|
||||
│ PocketBase API Request │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ HTTP Request Processing │ │
|
||||
│ │ │ │
|
||||
│ │ ┌─────────────────┐ ┌─────────────────┐ ┌──────────────────┐ │ │
|
||||
│ │ │ Prepare │ │ Execute │ │ Handle │ │ │
|
||||
│ │ │ Request │ │ HTTP POST │ │ Response │ │ │
|
||||
│ │ │ │ │ │ │ │ │ │
|
||||
│ │ │ • URL: │ │ • curl -s -w │ │ • Check HTTP │ │ │
|
||||
│ │ │ PB_API_URL │ │ "%{http_code}"│ │ 200/201 │ │ │
|
||||
│ │ │ • Method: POST │ │ • -X POST │ │ • Extract "id" │ │ │
|
||||
│ │ │ • Content-Type: │ │ • -L (follow │ │ from response │ │ │
|
||||
│ │ │ application/ │ │ redirects) │ │ • Store in │ │ │
|
||||
│ │ │ json │ │ • JSON body │ │ PB_RECORD_ID │ │ │
|
||||
│ │ └─────────────────┘ └─────────────────┘ └──────────────────┘ │ │
|
||||
│ └─────────────────────────────────────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## LXC API Reporting Flow
|
||||
## LXC API Reporting Flow — `post_to_api()`
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ POST_TO_API() Flow │
|
||||
│ Send LXC container installation data to API │
|
||||
│ post_to_api() Flow │
|
||||
│ POST → Create LXC telemetry record in PocketBase │
|
||||
└─────────────────────┬───────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ LXC Data Preparation │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ LXC-Specific Data Collection │ │
|
||||
│ │ │ │
|
||||
│ │ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────────┐ │ │
|
||||
│ │ │ Set LXC │ │ Include LXC │ │ Set Status │ │ │
|
||||
│ │ │ Type │ │ Variables │ │ Information │ │
|
||||
│ │ │ │ │ │ │ │ │
|
||||
│ │ │ • ct_type: 1 │ │ • DISK_SIZE │ │ • status: │ │
|
||||
│ │ │ • type: "lxc" │ │ • CORE_COUNT │ │ "installing" │ │
|
||||
│ │ │ • Include all │ │ • RAM_SIZE │ │ • Include all │ │
|
||||
│ │ │ LXC data │ │ • var_os │ │ tracking data │ │
|
||||
│ │ │ │ │ • var_version │ │ │ │
|
||||
│ │ │ │ │ • DISABLEIP6 │ │ │ │
|
||||
│ │ │ │ │ • NSAPP │ │ │ │
|
||||
│ │ │ │ │ • METHOD │ │ │ │
|
||||
│ │ │ │ │ • pve_version │ │ │ │
|
||||
│ │ │ │ │ • random_id │ │ │ │
|
||||
│ │ └─────────────────┘ └─────────────────┘ └─────────────────────┘ │ │
|
||||
│ └─────────────────────────────────────────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ JSON Payload Creation │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ JSON Structure Generation │ │
|
||||
│ │ │ │
|
||||
│ │ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────────┐ │ │
|
||||
│ │ │ Create JSON │ │ Validate │ │ Format for │ │ │
|
||||
│ │ │ Structure │ │ Data │ │ API Request │ │
|
||||
│ │ │ │ │ │ │ │ │
|
||||
│ │ │ • Use heredoc │ │ • Check all │ │ • Ensure proper │ │
|
||||
│ │ │ syntax │ │ variables │ │ JSON format │ │
|
||||
│ │ │ • Include all │ │ are set │ │ • Escape special │ │
|
||||
│ │ │ required │ │ • Validate │ │ characters │ │
|
||||
│ │ │ fields │ │ data types │ │ • Set content │ │
|
||||
│ │ │ • Format │ │ • Handle │ │ type │ │
|
||||
│ │ │ properly │ │ missing │ │ │ │
|
||||
│ │ │ │ │ values │ │ │ │
|
||||
│ │ └─────────────────┘ └─────────────────┘ └─────────────────────┘ │ │
|
||||
│ └─────────────────────────────────────────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## VM API Reporting Flow
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ POST_TO_API_VM() Flow │
|
||||
│ Send VM installation data to API │
|
||||
│ Prerequisites: curl? ──► DIAGNOSTICS="yes"? ──► RANDOM_UUID set? │
|
||||
│ (return silently on any failure) │
|
||||
└─────────────────────┬───────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ VM Data Preparation │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ VM-Specific Data Collection │ │
|
||||
│ │ │ │
|
||||
│ │ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────────┐ │ │
|
||||
│ │ │ Check │ │ Set VM │ │ Process Disk │ │ │
|
||||
│ │ │ Diagnostics │ │ Type │ │ Size │ │
|
||||
│ │ │ File │ │ │ │ │ │
|
||||
│ │ │ │ │ • ct_type: 2 │ │ • Remove 'G' │ │
|
||||
│ │ │ • Check file │ │ • type: "vm" │ │ suffix │ │
|
||||
│ │ │ existence │ │ • Include all │ │ • Convert to │ │
|
||||
│ │ │ • Read │ │ VM data │ │ numeric value │ │
|
||||
│ │ │ DIAGNOSTICS │ │ │ │ • Store in │ │
|
||||
│ │ │ setting │ │ │ │ DISK_SIZE_API │ │
|
||||
│ │ │ • Parse value │ │ │ │ │ │
|
||||
│ │ └─────────────────┘ └─────────────────┘ └─────────────────────┘ │ │
|
||||
│ └─────────────────────────────────────────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ VM JSON Payload Creation │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ VM-Specific JSON Structure │ │
|
||||
│ │ │ │
|
||||
│ │ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────────┐ │ │
|
||||
│ │ │ Include VM │ │ Set VM │ │ Format VM │ │ │
|
||||
│ │ │ Variables │ │ Status │ │ Data for API │ │
|
||||
│ │ │ │ │ │ │ │ │
|
||||
│ │ │ • DISK_SIZE_API │ │ • status: │ │ • Ensure proper │ │
|
||||
│ │ │ • CORE_COUNT │ │ "installing" │ │ JSON format │ │
|
||||
│ │ │ • RAM_SIZE │ │ • Include all │ │ • Handle VM- │ │
|
||||
│ │ │ • var_os │ │ tracking │ │ specific data │ │
|
||||
│ │ │ • var_version │ │ information │ │ • Set appropriate │ │
|
||||
│ │ │ • NSAPP │ │ │ │ content type │ │
|
||||
│ │ │ • METHOD │ │ │ │ │ │
|
||||
│ │ │ • pve_version │ │ │ │ │ │
|
||||
│ │ │ • random_id │ │ │ │ │ │
|
||||
│ │ └─────────────────┘ └─────────────────┘ └─────────────────────┘ │ │
|
||||
│ └─────────────────────────────────────────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## Status Update Flow
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ POST_UPDATE_TO_API() Flow │
|
||||
│ Send installation completion status to API │
|
||||
│ LXC Data Preparation │
|
||||
│ │
|
||||
│ ┌─────────────────┐ ┌─────────────────────┐ ┌───────────────────┐ │
|
||||
│ │ Set LXC type │ │ Collect variables │ │ Set initial │ │
|
||||
│ │ │ │ │ │ status │ │
|
||||
│ │ • ct_type: 1 │ │ • DISK_SIZE │ │ │ │
|
||||
│ │ • type: "lxc" │ │ • CORE_COUNT │ │ • status: │ │
|
||||
│ │ │ │ • RAM_SIZE │ │ "installing" │ │
|
||||
│ │ │ │ • var_os, var_version│ │ • random_id: │ │
|
||||
│ │ │ │ • NSAPP, METHOD │ │ RANDOM_UUID │ │
|
||||
│ │ │ │ • pve_version │ │ │ │
|
||||
│ └─────────────────┘ └─────────────────────┘ └───────────────────┘ │
|
||||
└─────────────────────┬───────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ Update Prevention Check │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ Duplicate Update Prevention │ │
|
||||
│ │ │ │
|
||||
│ │ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────────┐ │ │
|
||||
│ │ │ Check │ │ Set Flag │ │ Return Early │ │ │
|
||||
│ │ │ POST_UPDATE_ │ │ if First │ │ if Already │ │
|
||||
│ │ │ DONE │ │ Update │ │ Updated │ │
|
||||
│ │ │ │ │ │ │ │ │
|
||||
│ │ │ • Check if │ │ • Set │ │ • Return 0 │ │
|
||||
│ │ │ already │ │ POST_UPDATE_ │ │ • Skip API call │ │
|
||||
│ │ │ updated │ │ DONE=true │ │ • Prevent │ │
|
||||
│ │ │ • Prevent │ │ • Continue │ │ duplicate │ │
|
||||
│ │ │ duplicate │ │ with update │ │ requests │ │
|
||||
│ │ │ requests │ │ │ │ │ │
|
||||
│ │ └─────────────────┘ └─────────────────┘ └─────────────────────┘ │ │
|
||||
│ └─────────────────────────────────────────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ Status and Error Processing │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ Status Determination │ │
|
||||
│ │ │ │
|
||||
│ │ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────────┐ │ │
|
||||
│ │ │ Determine │ │ Get Error │ │ Prepare Status │ │ │
|
||||
│ │ │ Status │ │ Description │ │ Data │ │
|
||||
│ │ │ │ │ │ │ │ │
|
||||
│ │ │ • status: │ │ • Call │ │ • Include status │ │
|
||||
│ │ │ "success" or │ │ get_error_ │ │ • Include error │ │
|
||||
│ │ │ "failed" │ │ description() │ │ description │ │
|
||||
│ │ │ • Set exit │ │ • Get human- │ │ • Include random │ │
|
||||
│ │ │ code based │ │ readable │ │ ID for tracking │ │
|
||||
│ │ │ on status │ │ error message │ │ │ │
|
||||
│ │ │ • Default to │ │ • Handle │ │ │ │
|
||||
│ │ │ error if │ │ unknown │ │ │ │
|
||||
│ │ │ not set │ │ errors │ │ │ │
|
||||
│ │ └─────────────────┘ └─────────────────┘ └─────────────────────┘ │ │
|
||||
│ └─────────────────────────────────────────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ Status Update API Request │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ Status Update Payload Creation │ │
|
||||
│ │ │ │
|
||||
│ │ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────────┐ │ │
|
||||
│ │ │ Create │ │ Send Status │ │ Mark Update │ │ │
|
||||
│ │ │ Status JSON │ │ Update │ │ Complete │ │
|
||||
│ │ │ │ │ │ │ │ │
|
||||
│ │ │ • Include │ │ • POST to │ │ • Set │ │
|
||||
│ │ │ status │ │ updatestatus │ │ POST_UPDATE_ │ │
|
||||
│ │ │ • Include │ │ endpoint │ │ DONE=true │ │
|
||||
│ │ │ error │ │ • Include JSON │ │ • Prevent further │ │
|
||||
│ │ │ description │ │ payload │ │ updates │ │
|
||||
│ │ │ • Include │ │ • Handle │ │ • Complete │ │
|
||||
│ │ │ random_id │ │ response │ │ process │ │
|
||||
│ │ │ │ │ gracefully │ │ │ │
|
||||
│ │ └─────────────────┘ └─────────────────┘ └─────────────────────┘ │ │
|
||||
│ └─────────────────────────────────────────────────────────────────────────────┘ │
|
||||
│ POST → PB_API_URL │
|
||||
│ http://db.community-scripts.org/api/collections/_dev_telemetry_data/records │
|
||||
│ │
|
||||
│ Response (HTTP 200/201): │
|
||||
│ { "id": "abc123def456789", ... } │
|
||||
│ │ │
|
||||
│ └──► PB_RECORD_ID = "abc123def456789" │
|
||||
└─────────────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## Error Description Flow
|
||||
## VM API Reporting Flow — `post_to_api_vm()`
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ GET_ERROR_DESCRIPTION() Flow │
|
||||
│ Convert numeric exit codes to human-readable explanations │
|
||||
│ post_to_api_vm() Flow │
|
||||
│ POST → Create VM telemetry record in PocketBase │
|
||||
└─────────────────────┬───────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ Error Code Classification │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ Error Code Categories │ │
|
||||
│ │ │ │
|
||||
│ │ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────────┐ │ │
|
||||
│ │ │ General │ │ Network │ │ LXC-Specific │ │ │
|
||||
│ │ │ System │ │ Errors │ │ Errors │ │
|
||||
│ │ │ Errors │ │ │ │ │ │
|
||||
│ │ │ │ │ • 18: Connection│ │ • 100-101: LXC │ │
|
||||
│ │ │ • 0-9: Basic │ │ failed │ │ install errors │ │
|
||||
│ │ │ errors │ │ • 22: Invalid │ │ • 200-209: LXC │ │
|
||||
│ │ │ • 126-128: │ │ argument │ │ creation errors │ │
|
||||
│ │ │ Command │ │ • 28: No space │ │ │ │
|
||||
│ │ │ errors │ │ • 35: Timeout │ │ │ │
|
||||
│ │ │ • 129-143: │ │ • 56: TLS error │ │ │ │
|
||||
│ │ │ Signal │ │ • 60: SSL cert │ │ │ │
|
||||
│ │ │ errors │ │ error │ │ │ │
|
||||
│ │ │ • 152: Resource │ │ │ │ │ │
|
||||
│ │ │ limit │ │ │ │ │ │
|
||||
│ │ │ • 255: Unknown │ │ │ │ │ │
|
||||
│ │ │ critical │ │ │ │ │ │
|
||||
│ │ └─────────────────┘ └─────────────────┘ └─────────────────────┘ │ │
|
||||
│ └─────────────────────────────────────────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────────────────────────┘
|
||||
│ Read /usr/local/community-scripts/diagnostics │
|
||||
│ Extract DIAGNOSTICS=yes/no from file │
|
||||
└─────────────────────┬───────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ Error Message Return │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ Error Message Formatting │ │
|
||||
│ │ │ │
|
||||
│ │ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────────┐ │ │
|
||||
│ │ │ Match Error │ │ Return │ │ Default Case │ │ │
|
||||
│ │ │ Code │ │ Description │ │ │ │
|
||||
│ │ │ │ │ │ │ │ │
|
||||
│ │ │ • Use case │ │ • Return │ │ • Return "Unknown │ │
|
||||
│ │ │ statement │ │ human- │ │ error code │ │
|
||||
│ │ │ • Match │ │ readable │ │ (exit_code)" │ │
|
||||
│ │ │ specific │ │ message │ │ • Handle │ │
|
||||
│ │ │ codes │ │ • Include │ │ unrecognized │ │
|
||||
│ │ │ • Handle │ │ context │ │ codes │ │
|
||||
│ │ │ ranges │ │ information │ │ • Provide fallback │ │
|
||||
│ │ │ │ │ │ │ message │ │
|
||||
│ │ └─────────────────┘ └─────────────────┘ └─────────────────────┘ │ │
|
||||
│ └─────────────────────────────────────────────────────────────────────────────┘ │
|
||||
│ Prerequisites: curl? ──► DIAGNOSTICS="yes"? ──► RANDOM_UUID set? │
|
||||
│ (return silently on any failure) │
|
||||
└─────────────────────┬───────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ VM Data Preparation │
|
||||
│ │
|
||||
│ ┌─────────────────┐ ┌─────────────────────┐ ┌───────────────────┐ │
|
||||
│ │ Set VM type │ │ Process disk size │ │ Set initial │ │
|
||||
│ │ │ │ │ │ status │ │
|
||||
│ │ • ct_type: 2 │ │ • Strip 'G' suffix │ │ │ │
|
||||
│ │ • type: "vm" │ │ "20G" → 20 │ │ • status: │ │
|
||||
│ │ │ │ • Store in │ │ "installing" │ │
|
||||
│ │ │ │ DISK_SIZE_API │ │ • random_id: │ │
|
||||
│ │ │ │ │ │ RANDOM_UUID │ │
|
||||
│ └─────────────────┘ └─────────────────────┘ └───────────────────┘ │
|
||||
└─────────────────────┬───────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ POST → PB_API_URL │
|
||||
│ http://db.community-scripts.org/api/collections/_dev_telemetry_data/records │
|
||||
│ │
|
||||
│ Response (HTTP 200/201): │
|
||||
│ { "id": "xyz789abc012345", ... } │
|
||||
│ │ │
|
||||
│ └──► PB_RECORD_ID = "xyz789abc012345" │
|
||||
└─────────────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## Status Update Flow — `post_update_to_api()`
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ post_update_to_api(status, exit_code) Flow │
|
||||
│ PATCH → Update existing PocketBase record with final status │
|
||||
└─────────────────────┬───────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ Duplicate Prevention Check │
|
||||
│ │
|
||||
│ ┌─────────────────┐ ┌──────────────────────────────────────────────┐ │
|
||||
│ │ Check │ │ POST_UPDATE_DONE == "true"? │ │
|
||||
│ │ POST_UPDATE_ │───►│ │ │
|
||||
│ │ DONE flag │ │ YES → return 0 (skip PATCH) │ │
|
||||
│ │ │ │ NO → continue │ │
|
||||
│ └─────────────────┘ └──────────────────────────────────────────────┘ │
|
||||
└─────────────────────┬───────────────────────────────────────────────────────────┘
|
||||
│ (first call only)
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ Prerequisites: curl? ──► DIAGNOSTICS="yes"? ──► RANDOM_UUID set? │
|
||||
└─────────────────────┬───────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ Status Mapping │
|
||||
│ │
|
||||
│ Input $1 │ PocketBase status │ exit_code │ error │
|
||||
│ ─────────────────┼─────────────────────┼──────────────┼────────────────────── │
|
||||
│ "done"/"success" │ "sucess" │ 0 │ "" │
|
||||
│ "failed" │ "failed" │ from $2 │ explain_exit_code() │
|
||||
│ anything else │ "unknown" │ from $2 │ explain_exit_code() │
|
||||
│ │
|
||||
│ Note: PocketBase schema spells it "sucess" intentionally │
|
||||
└─────────────────────┬───────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ Record ID Resolution │
|
||||
│ │
|
||||
│ ┌──────────────────────────┐ ┌──────────────────────────────────────┐ │
|
||||
│ │ PB_RECORD_ID set? │ │ Fallback: GET lookup │ │
|
||||
│ │ │ │ │ │
|
||||
│ │ YES → use PB_RECORD_ID │ │ GET PB_API_URL │ │
|
||||
│ │ │ │ ?filter=(random_id='UUID') │ │
|
||||
│ │ NO → try GET lookup ───┼───►│ &fields=id │ │
|
||||
│ │ │ │ &perPage=1 │ │
|
||||
│ │ │ │ │ │
|
||||
│ │ │ │ Extract "id" from response │ │
|
||||
│ │ │ │ If not found → set flag, return │ │
|
||||
│ └──────────────────────────┘ └──────────────────────────────────────┘ │
|
||||
└─────────────────────┬───────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ PATCH Request │
|
||||
│ │
|
||||
│ PATCH → PB_API_URL/{record_id} │
|
||||
│ http://db.community-scripts.org/api/collections/_dev_telemetry_data/ │
|
||||
│ records/{record_id} │
|
||||
│ │
|
||||
│ Payload: │
|
||||
│ { │
|
||||
│ "status": "sucess" | "failed" | "unknown", │
|
||||
│ "error": "..." | "", │
|
||||
│ "exit_code": 0 | <numeric> │
|
||||
│ } │
|
||||
│ │
|
||||
│ ──► POST_UPDATE_DONE = true (prevents future calls) │
|
||||
└─────────────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## Error Description Flow — `explain_exit_code()`
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ explain_exit_code(code) Flow │
|
||||
│ Convert numeric exit codes to human-readable descriptions │
|
||||
│ Canonical function — used by api.func AND error_handler.func │
|
||||
└─────────────────────┬───────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ Exit Code Classification (non-overlapping ranges) │
|
||||
│ │
|
||||
│ ┌─────────────────┐ ┌──────────────────┐ ┌──────────────────────────┐ │
|
||||
│ │ Generic/Shell │ │ curl/wget │ │ APT/DPKG │ │
|
||||
│ │ 1–2 │ │ 6, 7, 22, 28, 35│ │ 100–102, 255 │ │
|
||||
│ └─────────────────┘ └──────────────────┘ └──────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌─────────────────┐ ┌──────────────────┐ ┌──────────────────────────┐ │
|
||||
│ │ System/Signals │ │ Systemd/Service │ │ Python/pip/uv │ │
|
||||
│ │ 124–143 │ │ 150–154 │ │ 160–162 │ │
|
||||
│ └─────────────────┘ └──────────────────┘ └──────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌─────────────────┐ ┌──────────────────┐ ┌──────────────────────────┐ │
|
||||
│ │ PostgreSQL │ │ MySQL/MariaDB │ │ MongoDB │ │
|
||||
│ │ 170–173 │ │ 180–183 │ │ 190–193 │ │
|
||||
│ └─────────────────┘ └──────────────────┘ └──────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌─────────────────┐ ┌──────────────────┐ │
|
||||
│ │ Proxmox │ │ Node.js/npm │ │
|
||||
│ │ 200–231 │ │ 243–249 │ │
|
||||
│ └─────────────────┘ └──────────────────┘ │
|
||||
└─────────────────────┬───────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ case "$code" in │
|
||||
│ <matched>) echo "<description>" ;; │
|
||||
│ *) echo "Unknown error" ;; │
|
||||
│ esac │
|
||||
└─────────────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## Complete Installation Lifecycle
|
||||
|
||||
```
|
||||
┌──────────────────────────────────────────────────────────────┐
|
||||
│ Installation Script (e.g. build.func / vm-core.func) │
|
||||
└────────┬─────────────────────────────────────────────────────┘
|
||||
│
|
||||
│ 1. source api.func
|
||||
│ 2. Set DIAGNOSTICS, RANDOM_UUID, NSAPP, etc.
|
||||
│
|
||||
▼
|
||||
┌──────────────────────────────────────────────────────────────┐
|
||||
│ post_to_api() / post_to_api_vm() │
|
||||
│ │
|
||||
│ POST → PB_API_URL │
|
||||
│ Body: { ..., "status": "installing", "random_id": "..." } │
|
||||
│ │
|
||||
│ Response → PB_RECORD_ID = "abc123def456789" │
|
||||
└────────┬─────────────────────────────────────────────────────┘
|
||||
│
|
||||
│ 3. Installation proceeds...
|
||||
│ (container/VM creation, package install, etc.)
|
||||
│
|
||||
▼
|
||||
┌──────────────────────────────────────────────────────────────┐
|
||||
│ post_update_to_api("done", 0) │
|
||||
│ or │
|
||||
│ post_update_to_api("failed", $exit_code) │
|
||||
│ │
|
||||
│ PATCH → PB_API_URL/{PB_RECORD_ID} │
|
||||
│ Body: { "status": "sucess", "error": "", "exit_code": 0 } │
|
||||
│ or { "status": "failed", "error": "...", "exit_code": N }│
|
||||
│ │
|
||||
│ POST_UPDATE_DONE = true │
|
||||
└──────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## Integration Points
|
||||
|
||||
### With Installation Scripts
|
||||
- **build.func**: Sends LXC installation data
|
||||
- **vm-core.func**: Sends VM installation data
|
||||
- **install.func**: Reports installation status
|
||||
- **alpine-install.func**: Reports Alpine installation data
|
||||
- **build.func**: Calls `post_to_api()` for LXC creation, then `post_update_to_api()` on completion
|
||||
- **vm-core.func**: Calls `post_to_api_vm()` for VM creation, then `post_update_to_api()` on completion
|
||||
- **install.func / alpine-install.func**: Reports installation status via `post_update_to_api()`
|
||||
|
||||
### With Error Handling
|
||||
- **error_handler.func**: Provides error explanations
|
||||
- **core.func**: Uses error descriptions in silent execution
|
||||
- **Diagnostic reporting**: Tracks error patterns
|
||||
- **error_handler.func**: Uses `explain_exit_code()` for human-readable error messages
|
||||
- **Diagnostic reporting**: PocketBase records track error patterns anonymously
|
||||
|
||||
### External Dependencies
|
||||
- **curl**: HTTP client for API communication
|
||||
- **Community Scripts API**: External API endpoint
|
||||
- **Network connectivity**: Required for API communication
|
||||
- **curl**: HTTP client for PocketBase API communication
|
||||
- **PocketBase**: Backend at `http://db.community-scripts.org`
|
||||
- **Network connectivity**: Required for API communication (failures are silently ignored)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -2,26 +2,42 @@
|
||||
|
||||
## Overview
|
||||
|
||||
This document describes how `api.func` integrates with other components in the Proxmox Community Scripts project, including dependencies, data flow, and API surface.
|
||||
This document describes how `api.func` integrates with other components in the Proxmox Community Scripts project. The telemetry backend is **PocketBase** at `http://db.community-scripts.org`, using the `_dev_telemetry_data` collection.
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
Installation Scripts ──► api.func ──► PocketBase (db.community-scripts.org)
|
||||
│
|
||||
├─ POST → create record (status: "installing")
|
||||
├─ PATCH → update record (status: "sucess"/"failed")
|
||||
└─ GET → lookup record by random_id (fallback)
|
||||
```
|
||||
|
||||
### Key Design Points
|
||||
- **POST** creates a new telemetry record and returns a PocketBase `id`
|
||||
- **PATCH** updates the existing record using that `id` (or a GET lookup by `random_id`)
|
||||
- All communication is fire-and-forget — failures never block the installation
|
||||
- `explain_exit_code()` is the canonical function for exit-code-to-description mapping
|
||||
|
||||
## Dependencies
|
||||
|
||||
### External Dependencies
|
||||
|
||||
#### Required Commands
|
||||
- **`curl`**: HTTP client for API communication
|
||||
- **`uuidgen`**: Generate unique identifiers (optional, can use other methods)
|
||||
- **`curl`**: HTTP client for PocketBase API communication
|
||||
|
||||
#### Optional Commands
|
||||
- **None**: No other external command dependencies
|
||||
- **`uuidgen`**: Generate unique identifiers (any UUID source works)
|
||||
- **`pveversion`**: Retrieve Proxmox VE version (gracefully skipped if missing)
|
||||
|
||||
### Internal Dependencies
|
||||
|
||||
#### Environment Variables from Other Scripts
|
||||
- **build.func**: Provides container creation variables
|
||||
- **build.func**: Provides container creation variables (`CT_TYPE`, `DISK_SIZE`, etc.)
|
||||
- **vm-core.func**: Provides VM creation variables
|
||||
- **core.func**: Provides system information variables
|
||||
- **Installation scripts**: Provide application-specific variables
|
||||
- **core.func**: Provides system information
|
||||
- **Installation scripts**: Provide application-specific variables (`NSAPP`, `METHOD`)
|
||||
|
||||
## Integration Points
|
||||
|
||||
@@ -29,48 +45,41 @@ This document describes how `api.func` integrates with other components in the P
|
||||
|
||||
#### LXC Container Reporting
|
||||
```bash
|
||||
# build.func uses api.func for container reporting
|
||||
source core.func
|
||||
source api.func
|
||||
source build.func
|
||||
|
||||
# Set up API reporting
|
||||
export DIAGNOSTICS="yes"
|
||||
export RANDOM_UUID="$(uuidgen)"
|
||||
|
||||
# Container creation with API reporting
|
||||
create_container() {
|
||||
# Set container parameters
|
||||
export CT_TYPE=1
|
||||
export DISK_SIZE="$var_disk"
|
||||
export CORE_COUNT="$var_cpu"
|
||||
export RAM_SIZE="$var_ram"
|
||||
export var_os="$var_os"
|
||||
export var_version="$var_version"
|
||||
export NSAPP="$APP"
|
||||
export METHOD="install"
|
||||
# Set container parameters
|
||||
export CT_TYPE=1
|
||||
export DISK_SIZE="$var_disk"
|
||||
export CORE_COUNT="$var_cpu"
|
||||
export RAM_SIZE="$var_ram"
|
||||
export var_os="$var_os"
|
||||
export var_version="$var_version"
|
||||
export NSAPP="$APP"
|
||||
export METHOD="install"
|
||||
|
||||
# Report installation start
|
||||
post_to_api
|
||||
# POST → creates record in PocketBase, saves PB_RECORD_ID
|
||||
post_to_api
|
||||
|
||||
# Container creation using build.func
|
||||
# ... build.func container creation logic ...
|
||||
# ... container creation via build.func ...
|
||||
|
||||
# Report completion
|
||||
if [[ $? -eq 0 ]]; then
|
||||
post_update_to_api "success" 0
|
||||
else
|
||||
post_update_to_api "failed" $?
|
||||
fi
|
||||
}
|
||||
# PATCH → updates the record with final status
|
||||
if [[ $? -eq 0 ]]; then
|
||||
post_update_to_api "done" 0
|
||||
else
|
||||
post_update_to_api "failed" $?
|
||||
fi
|
||||
```
|
||||
|
||||
#### Error Reporting Integration
|
||||
```bash
|
||||
# build.func uses api.func for error reporting
|
||||
handle_container_error() {
|
||||
local exit_code=$1
|
||||
local error_msg=$(get_error_description $exit_code)
|
||||
local error_msg=$(explain_exit_code $exit_code)
|
||||
|
||||
echo "Container creation failed: $error_msg"
|
||||
post_update_to_api "failed" $exit_code
|
||||
@@ -81,93 +90,54 @@ handle_container_error() {
|
||||
|
||||
#### VM Installation Reporting
|
||||
```bash
|
||||
# vm-core.func uses api.func for VM reporting
|
||||
source core.func
|
||||
source api.func
|
||||
source vm-core.func
|
||||
|
||||
# Set up VM API reporting
|
||||
# VM reads DIAGNOSTICS from file
|
||||
mkdir -p /usr/local/community-scripts
|
||||
echo "DIAGNOSTICS=yes" > /usr/local/community-scripts/diagnostics
|
||||
|
||||
export RANDOM_UUID="$(uuidgen)"
|
||||
|
||||
# VM creation with API reporting
|
||||
create_vm() {
|
||||
# Set VM parameters
|
||||
export DISK_SIZE="${var_disk}G"
|
||||
export CORE_COUNT="$var_cpu"
|
||||
export RAM_SIZE="$var_ram"
|
||||
export var_os="$var_os"
|
||||
export var_version="$var_version"
|
||||
export NSAPP="$APP"
|
||||
export METHOD="install"
|
||||
# Set VM parameters
|
||||
export DISK_SIZE="${var_disk}G"
|
||||
export CORE_COUNT="$var_cpu"
|
||||
export RAM_SIZE="$var_ram"
|
||||
export var_os="$var_os"
|
||||
export var_version="$var_version"
|
||||
export NSAPP="$APP"
|
||||
export METHOD="install"
|
||||
|
||||
# Report VM installation start
|
||||
post_to_api_vm
|
||||
# POST → creates record in PocketBase (ct_type=2, type="vm")
|
||||
post_to_api_vm
|
||||
|
||||
# VM creation using vm-core.func
|
||||
# ... vm-core.func VM creation logic ...
|
||||
# ... VM creation via vm-core.func ...
|
||||
|
||||
# Report completion
|
||||
post_update_to_api "success" 0
|
||||
}
|
||||
```
|
||||
|
||||
### With core.func
|
||||
|
||||
#### System Information Integration
|
||||
```bash
|
||||
# core.func provides system information for api.func
|
||||
source core.func
|
||||
source api.func
|
||||
|
||||
# Get system information for API reporting
|
||||
get_system_info_for_api() {
|
||||
# Get PVE version using core.func utilities
|
||||
local pve_version=$(pveversion | awk -F'[/ ]' '{print $2}')
|
||||
|
||||
# Set API parameters
|
||||
export var_os="$var_os"
|
||||
export var_version="$var_version"
|
||||
|
||||
# Use core.func error handling with api.func reporting
|
||||
if silent apt-get update; then
|
||||
post_update_to_api "success" 0
|
||||
else
|
||||
post_update_to_api "failed" $?
|
||||
fi
|
||||
}
|
||||
# PATCH → finalizes record
|
||||
post_update_to_api "done" 0
|
||||
```
|
||||
|
||||
### With error_handler.func
|
||||
|
||||
#### Error Description Integration
|
||||
```bash
|
||||
# error_handler.func uses api.func for error descriptions
|
||||
source core.func
|
||||
source error_handler.func
|
||||
source api.func
|
||||
|
||||
# Enhanced error handler with API reporting
|
||||
enhanced_error_handler() {
|
||||
local exit_code=${1:-$?}
|
||||
local command=${2:-${BASH_COMMAND:-unknown}}
|
||||
|
||||
# Get error description from api.func
|
||||
local error_msg=$(get_error_description $exit_code)
|
||||
# explain_exit_code() is the canonical error description function
|
||||
local error_msg=$(explain_exit_code $exit_code)
|
||||
|
||||
# Display error information
|
||||
echo "Error $exit_code: $error_msg"
|
||||
echo "Command: $command"
|
||||
|
||||
# Report error to API
|
||||
export DIAGNOSTICS="yes"
|
||||
export RANDOM_UUID="$(uuidgen)"
|
||||
# PATCH the telemetry record with failure details
|
||||
post_update_to_api "failed" $exit_code
|
||||
|
||||
# Use standard error handler
|
||||
error_handler $exit_code $command
|
||||
}
|
||||
```
|
||||
|
||||
@@ -175,32 +145,28 @@ enhanced_error_handler() {
|
||||
|
||||
#### Installation Process Reporting
|
||||
```bash
|
||||
# install.func uses api.func for installation reporting
|
||||
source core.func
|
||||
source api.func
|
||||
source install.func
|
||||
|
||||
# Installation with API reporting
|
||||
install_package_with_reporting() {
|
||||
local package="$1"
|
||||
|
||||
# Set up API reporting
|
||||
export DIAGNOSTICS="yes"
|
||||
export RANDOM_UUID="$(uuidgen)"
|
||||
export NSAPP="$package"
|
||||
export METHOD="install"
|
||||
|
||||
# Report installation start
|
||||
# POST → create telemetry record
|
||||
post_to_api
|
||||
|
||||
# Package installation using install.func
|
||||
if install_package "$package"; then
|
||||
echo "$package installed successfully"
|
||||
post_update_to_api "success" 0
|
||||
post_update_to_api "done" 0
|
||||
return 0
|
||||
else
|
||||
local exit_code=$?
|
||||
local error_msg=$(get_error_description $exit_code)
|
||||
local error_msg=$(explain_exit_code $exit_code)
|
||||
echo "$package installation failed: $error_msg"
|
||||
post_update_to_api "failed" $exit_code
|
||||
return $exit_code
|
||||
@@ -208,270 +174,105 @@ install_package_with_reporting() {
|
||||
}
|
||||
```
|
||||
|
||||
### With alpine-install.func
|
||||
|
||||
#### Alpine Installation Reporting
|
||||
```bash
|
||||
# alpine-install.func uses api.func for Alpine reporting
|
||||
source core.func
|
||||
source api.func
|
||||
source alpine-install.func
|
||||
|
||||
# Alpine installation with API reporting
|
||||
install_alpine_with_reporting() {
|
||||
local app="$1"
|
||||
|
||||
# Set up API reporting
|
||||
export DIAGNOSTICS="yes"
|
||||
export RANDOM_UUID="$(uuidgen)"
|
||||
export NSAPP="$app"
|
||||
export METHOD="install"
|
||||
export var_os="alpine"
|
||||
|
||||
# Report Alpine installation start
|
||||
post_to_api
|
||||
|
||||
# Alpine installation using alpine-install.func
|
||||
if install_alpine_app "$app"; then
|
||||
echo "Alpine $app installed successfully"
|
||||
post_update_to_api "success" 0
|
||||
return 0
|
||||
else
|
||||
local exit_code=$?
|
||||
local error_msg=$(get_error_description $exit_code)
|
||||
echo "Alpine $app installation failed: $error_msg"
|
||||
post_update_to_api "failed" $exit_code
|
||||
return $exit_code
|
||||
fi
|
||||
}
|
||||
```
|
||||
|
||||
### With alpine-tools.func
|
||||
|
||||
#### Alpine Tools Reporting
|
||||
```bash
|
||||
# alpine-tools.func uses api.func for Alpine tools reporting
|
||||
source core.func
|
||||
source api.func
|
||||
source alpine-tools.func
|
||||
|
||||
# Alpine tools with API reporting
|
||||
run_alpine_tool_with_reporting() {
|
||||
local tool="$1"
|
||||
|
||||
# Set up API reporting
|
||||
export DIAGNOSTICS="yes"
|
||||
export RANDOM_UUID="$(uuidgen)"
|
||||
export NSAPP="alpine-tools"
|
||||
export METHOD="tool"
|
||||
|
||||
# Report tool execution start
|
||||
post_to_api
|
||||
|
||||
# Run Alpine tool using alpine-tools.func
|
||||
if run_alpine_tool "$tool"; then
|
||||
echo "Alpine tool $tool executed successfully"
|
||||
post_update_to_api "success" 0
|
||||
return 0
|
||||
else
|
||||
local exit_code=$?
|
||||
local error_msg=$(get_error_description $exit_code)
|
||||
echo "Alpine tool $tool failed: $error_msg"
|
||||
post_update_to_api "failed" $exit_code
|
||||
return $exit_code
|
||||
fi
|
||||
}
|
||||
```
|
||||
|
||||
### With passthrough.func
|
||||
|
||||
#### Hardware Passthrough Reporting
|
||||
```bash
|
||||
# passthrough.func uses api.func for hardware reporting
|
||||
source core.func
|
||||
source api.func
|
||||
source passthrough.func
|
||||
|
||||
# Hardware passthrough with API reporting
|
||||
configure_passthrough_with_reporting() {
|
||||
local hardware_type="$1"
|
||||
|
||||
# Set up API reporting
|
||||
export DIAGNOSTICS="yes"
|
||||
export RANDOM_UUID="$(uuidgen)"
|
||||
export NSAPP="passthrough"
|
||||
export METHOD="hardware"
|
||||
|
||||
# Report passthrough configuration start
|
||||
post_to_api
|
||||
|
||||
# Configure passthrough using passthrough.func
|
||||
if configure_passthrough "$hardware_type"; then
|
||||
echo "Hardware passthrough configured successfully"
|
||||
post_update_to_api "success" 0
|
||||
return 0
|
||||
else
|
||||
local exit_code=$?
|
||||
local error_msg=$(get_error_description $exit_code)
|
||||
echo "Hardware passthrough failed: $error_msg"
|
||||
post_update_to_api "failed" $exit_code
|
||||
return $exit_code
|
||||
fi
|
||||
}
|
||||
```
|
||||
|
||||
### With tools.func
|
||||
|
||||
#### Maintenance Operations Reporting
|
||||
```bash
|
||||
# tools.func uses api.func for maintenance reporting
|
||||
source core.func
|
||||
source api.func
|
||||
source tools.func
|
||||
|
||||
# Maintenance operations with API reporting
|
||||
run_maintenance_with_reporting() {
|
||||
local operation="$1"
|
||||
|
||||
# Set up API reporting
|
||||
export DIAGNOSTICS="yes"
|
||||
export RANDOM_UUID="$(uuidgen)"
|
||||
export NSAPP="maintenance"
|
||||
export METHOD="tool"
|
||||
|
||||
# Report maintenance start
|
||||
post_to_api
|
||||
|
||||
# Run maintenance using tools.func
|
||||
if run_maintenance_operation "$operation"; then
|
||||
echo "Maintenance operation $operation completed successfully"
|
||||
post_update_to_api "success" 0
|
||||
return 0
|
||||
else
|
||||
local exit_code=$?
|
||||
local error_msg=$(get_error_description $exit_code)
|
||||
echo "Maintenance operation $operation failed: $error_msg"
|
||||
post_update_to_api "failed" $exit_code
|
||||
return $exit_code
|
||||
fi
|
||||
}
|
||||
```
|
||||
|
||||
## Data Flow
|
||||
|
||||
### Input Data
|
||||
|
||||
#### Environment Variables from Other Scripts
|
||||
- **`CT_TYPE`**: Container type (1 for LXC, 2 for VM)
|
||||
- **`DISK_SIZE`**: Disk size in GB
|
||||
- **`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
|
||||
- **`METHOD`**: Installation method
|
||||
- **`DIAGNOSTICS`**: Enable/disable diagnostic reporting
|
||||
- **`RANDOM_UUID`**: Unique identifier for tracking
|
||||
#### Environment Variables
|
||||
| Variable | Source | Description |
|
||||
|----------|--------|-------------|
|
||||
| `CT_TYPE` | build.func | Container type (1=LXC, 2=VM) |
|
||||
| `DISK_SIZE` | build.func / vm-core.func | Disk size in GB (VMs may have `G` suffix) |
|
||||
| `CORE_COUNT` | build.func / vm-core.func | CPU core count |
|
||||
| `RAM_SIZE` | build.func / vm-core.func | RAM in MB |
|
||||
| `var_os` | core.func | Operating system type |
|
||||
| `var_version` | core.func | OS version |
|
||||
| `NSAPP` | Installation scripts | Application name |
|
||||
| `METHOD` | Installation scripts | Installation method |
|
||||
| `DIAGNOSTICS` | User config / diagnostics file | Enable/disable telemetry |
|
||||
| `RANDOM_UUID` | Caller | Session tracking UUID |
|
||||
|
||||
#### Function Parameters
|
||||
- **Exit codes**: Passed to `get_error_description()` and `post_update_to_api()`
|
||||
- **Status information**: Passed to `post_update_to_api()`
|
||||
- **API endpoints**: Hardcoded in functions
|
||||
- **Exit codes**: Passed to `explain_exit_code()` and `post_update_to_api()`
|
||||
- **Status strings**: Passed to `post_update_to_api()` (`"done"`, `"failed"`)
|
||||
|
||||
#### System Information
|
||||
- **PVE version**: Retrieved from `pveversion` command
|
||||
- **Disk size processing**: Processed for VM API (removes 'G' suffix)
|
||||
- **Error codes**: Retrieved from command exit codes
|
||||
- **PVE version**: Retrieved from `pveversion` command at runtime
|
||||
- **Disk size**: VM disk size is stripped of `G` suffix before sending
|
||||
|
||||
### Processing Data
|
||||
### Processing
|
||||
|
||||
#### API Request Preparation
|
||||
- **JSON payload creation**: Format data for API consumption
|
||||
- **Data validation**: Ensure required fields are present
|
||||
- **Error handling**: Handle missing or invalid data
|
||||
- **Content type setting**: Set appropriate HTTP headers
|
||||
#### Record Creation (POST)
|
||||
1. Validate prerequisites (curl, DIAGNOSTICS, RANDOM_UUID)
|
||||
2. Gather PVE version
|
||||
3. Build JSON payload with all telemetry fields
|
||||
4. `POST` to `PB_API_URL`
|
||||
5. Extract `PB_RECORD_ID` from PocketBase response (HTTP 200/201)
|
||||
|
||||
#### Error Processing
|
||||
- **Error code mapping**: Map numeric codes to descriptions
|
||||
- **Error message formatting**: Format error descriptions
|
||||
- **Unknown error handling**: Handle unrecognized error codes
|
||||
- **Fallback messages**: Provide default error messages
|
||||
|
||||
#### API Communication
|
||||
- **HTTP request preparation**: Prepare curl commands
|
||||
- **Response handling**: Capture HTTP response codes
|
||||
- **Error handling**: Handle network and API errors
|
||||
- **Duplicate prevention**: Prevent duplicate status updates
|
||||
#### Record Update (PATCH)
|
||||
1. Validate prerequisites + check `POST_UPDATE_DONE` flag
|
||||
2. Map status string → PocketBase select value (`"done"` → `"sucess"`)
|
||||
3. For failures: call `explain_exit_code()` to get error description
|
||||
4. Resolve record ID: use `PB_RECORD_ID` or fall back to GET lookup
|
||||
5. `PATCH` to `PB_API_URL/{record_id}` with status, error, exit_code
|
||||
6. Set `POST_UPDATE_DONE=true`
|
||||
|
||||
### Output Data
|
||||
|
||||
#### API Communication
|
||||
- **HTTP requests**: Sent to community-scripts.org API
|
||||
- **Response codes**: Captured from API responses
|
||||
- **Error information**: Reported to API
|
||||
- **Status updates**: Sent to API
|
||||
#### PocketBase Records
|
||||
- **POST response**: Returns record with `id` field → stored in `PB_RECORD_ID`
|
||||
- **PATCH response**: Updates record fields (status, error, exit_code)
|
||||
- **GET response**: Used for record ID lookup by `random_id` filter
|
||||
|
||||
#### Error Information
|
||||
- **Error descriptions**: Human-readable error messages
|
||||
- **Error codes**: Mapped to descriptions
|
||||
- **Context information**: Error context and details
|
||||
- **Fallback messages**: Default error messages
|
||||
|
||||
#### System State
|
||||
- **POST_UPDATE_DONE**: Prevents duplicate updates
|
||||
- **RESPONSE**: Stores API response
|
||||
- **JSON_PAYLOAD**: Stores formatted API data
|
||||
- **API_URL**: Stores API endpoint
|
||||
#### Internal State
|
||||
| Variable | Description |
|
||||
|----------|-------------|
|
||||
| `PB_RECORD_ID` | PocketBase record ID for PATCH calls |
|
||||
| `POST_UPDATE_DONE` | Flag preventing duplicate updates |
|
||||
|
||||
## API Surface
|
||||
|
||||
### Public Functions
|
||||
|
||||
#### Error Description
|
||||
- **`get_error_description()`**: Convert exit codes to explanations
|
||||
- **Parameters**: Exit code to explain
|
||||
- **Returns**: Human-readable explanation string
|
||||
- **Usage**: Called by other functions and scripts
|
||||
| Function | Purpose | HTTP Method |
|
||||
|----------|---------|-------------|
|
||||
| `explain_exit_code(code)` | Map exit code to description | — |
|
||||
| `post_to_api()` | Create LXC telemetry record | POST |
|
||||
| `post_to_api_vm()` | Create VM telemetry record | POST |
|
||||
| `post_update_to_api(status, exit_code)` | Update record with final status | PATCH |
|
||||
|
||||
#### API Communication
|
||||
- **`post_to_api()`**: Send LXC installation data
|
||||
- **`post_to_api_vm()`**: Send VM installation data
|
||||
- **`post_update_to_api()`**: Send status updates
|
||||
- **Parameters**: Status and exit code (for updates)
|
||||
- **Returns**: None
|
||||
- **Usage**: Called by installation scripts
|
||||
### PocketBase Collection Schema
|
||||
|
||||
### Internal Functions
|
||||
Collection: `_dev_telemetry_data`
|
||||
|
||||
#### None
|
||||
- All functions in api.func are public
|
||||
- No internal helper functions
|
||||
- Direct implementation of all functionality
|
||||
| Field | Type | Required | Description |
|
||||
|-------|------|----------|-------------|
|
||||
| `id` | text (auto) | yes | PocketBase record ID (15 chars) |
|
||||
| `random_id` | text | yes | Session UUID (min 8 chars, unique) |
|
||||
| `type` | select | yes | `"lxc"`, `"vm"`, `"addon"`, `"pve"` |
|
||||
| `ct_type` | number | yes | 1 (LXC) or 2 (VM) |
|
||||
| `nsapp` | text | yes | Application name |
|
||||
| `status` | select | yes | `"installing"`, `"sucess"`, `"failed"`, `"unknown"` |
|
||||
| `disk_size` | number | no | Disk size in GB |
|
||||
| `core_count` | number | no | CPU cores |
|
||||
| `ram_size` | number | no | RAM in MB |
|
||||
| `os_type` | text | no | OS type |
|
||||
| `os_version` | text | no | OS version |
|
||||
| `pve_version` | text | no | Proxmox VE version |
|
||||
| `method` | text | no | Installation method |
|
||||
| `error` | text | no | Error description |
|
||||
| `exit_code` | number | no | Numeric exit code |
|
||||
| `created` | autodate | auto | Record creation timestamp |
|
||||
| `updated` | autodate | auto | Last update timestamp |
|
||||
|
||||
### Global Variables
|
||||
> **Note**: The `status` field intentionally uses the spelling `"sucess"` (not `"success"`).
|
||||
|
||||
#### Configuration Variables
|
||||
- **`DIAGNOSTICS`**: Diagnostic reporting setting
|
||||
- **`RANDOM_UUID`**: Unique tracking identifier
|
||||
- **`POST_UPDATE_DONE`**: Duplicate update prevention
|
||||
|
||||
#### Data Variables
|
||||
- **`CT_TYPE`**: Container type
|
||||
- **`DISK_SIZE`**: Disk size
|
||||
- **`CORE_COUNT`**: CPU core count
|
||||
- **`RAM_SIZE`**: RAM size
|
||||
- **`var_os`**: Operating system
|
||||
- **`var_version`**: OS version
|
||||
- **`DISABLEIP6`**: IPv6 setting
|
||||
- **`NSAPP`**: Application namespace
|
||||
- **`METHOD`**: Installation method
|
||||
|
||||
#### Internal Variables
|
||||
- **`API_URL`**: API endpoint URL
|
||||
- **`JSON_PAYLOAD`**: API request payload
|
||||
- **`RESPONSE`**: API response
|
||||
- **`DISK_SIZE_API`**: Processed disk size for VM API
|
||||
### Configuration Variables
|
||||
| Variable | Value |
|
||||
|----------|-------|
|
||||
| `PB_URL` | `http://db.community-scripts.org` |
|
||||
| `PB_COLLECTION` | `_dev_telemetry_data` |
|
||||
| `PB_API_URL` | `${PB_URL}/api/collections/${PB_COLLECTION}/records` |
|
||||
|
||||
## Integration Patterns
|
||||
|
||||
@@ -479,45 +280,39 @@ run_maintenance_with_reporting() {
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
# Standard integration pattern
|
||||
|
||||
# 1. Source core.func first
|
||||
# 1. Source dependencies
|
||||
source core.func
|
||||
|
||||
# 2. Source api.func
|
||||
source api.func
|
||||
|
||||
# 3. Set up API reporting
|
||||
# 2. Enable telemetry
|
||||
export DIAGNOSTICS="yes"
|
||||
export RANDOM_UUID="$(uuidgen)"
|
||||
|
||||
# 4. Set application parameters
|
||||
# 3. Set application parameters
|
||||
export NSAPP="$APP"
|
||||
export METHOD="install"
|
||||
|
||||
# 5. Report installation start
|
||||
# 4. POST → create telemetry record in PocketBase
|
||||
post_to_api
|
||||
|
||||
# 6. Perform installation
|
||||
# 5. Perform installation
|
||||
# ... installation logic ...
|
||||
|
||||
# 7. Report completion
|
||||
post_update_to_api "success" 0
|
||||
# 6. PATCH → update record with final status
|
||||
post_update_to_api "done" 0
|
||||
```
|
||||
|
||||
### Minimal Integration Pattern
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
# Minimal integration pattern
|
||||
|
||||
source api.func
|
||||
|
||||
# Basic error reporting
|
||||
export DIAGNOSTICS="yes"
|
||||
export RANDOM_UUID="$(uuidgen)"
|
||||
|
||||
# Report failure
|
||||
# Report failure (PATCH via record lookup)
|
||||
post_update_to_api "failed" 127
|
||||
```
|
||||
|
||||
@@ -525,13 +320,10 @@ post_update_to_api "failed" 127
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
# Advanced integration pattern
|
||||
|
||||
source core.func
|
||||
source api.func
|
||||
source error_handler.func
|
||||
|
||||
# Set up comprehensive API reporting
|
||||
export DIAGNOSTICS="yes"
|
||||
export RANDOM_UUID="$(uuidgen)"
|
||||
export CT_TYPE=1
|
||||
@@ -542,12 +334,12 @@ export var_os="debian"
|
||||
export var_version="12"
|
||||
export METHOD="install"
|
||||
|
||||
# Enhanced error handling with API reporting
|
||||
# Enhanced error handler with PocketBase reporting
|
||||
enhanced_error_handler() {
|
||||
local exit_code=${1:-$?}
|
||||
local command=${2:-${BASH_COMMAND:-unknown}}
|
||||
|
||||
local error_msg=$(get_error_description $exit_code)
|
||||
local error_msg=$(explain_exit_code $exit_code)
|
||||
echo "Error $exit_code: $error_msg"
|
||||
|
||||
post_update_to_api "failed" $exit_code
|
||||
@@ -556,88 +348,39 @@ enhanced_error_handler() {
|
||||
|
||||
trap 'enhanced_error_handler' ERR
|
||||
|
||||
# Advanced operations with API reporting
|
||||
# POST → create record
|
||||
post_to_api
|
||||
|
||||
# ... operations ...
|
||||
post_update_to_api "success" 0
|
||||
|
||||
# PATCH → finalize
|
||||
post_update_to_api "done" 0
|
||||
```
|
||||
|
||||
## Error Handling Integration
|
||||
|
||||
### Automatic Error Reporting
|
||||
- **Error Descriptions**: Provides human-readable error messages
|
||||
- **API Integration**: Reports errors to community-scripts.org API
|
||||
- **Error Tracking**: Tracks error patterns for project improvement
|
||||
- **Diagnostic Data**: Contributes to anonymous usage analytics
|
||||
|
||||
### Manual Error Reporting
|
||||
- **Custom Error Codes**: Use appropriate error codes for different scenarios
|
||||
- **Error Context**: Provide context information for errors
|
||||
- **Status Updates**: Report both success and failure cases
|
||||
- **Error Analysis**: Analyze error patterns and trends
|
||||
- **Error Descriptions**: `explain_exit_code()` provides human-readable messages for all recognized exit codes
|
||||
- **PocketBase Integration**: Errors are recorded via PATCH with `status`, `error`, and `exit_code` fields
|
||||
- **Error Tracking**: Anonymous telemetry helps track common failure patterns
|
||||
- **Diagnostic Data**: Contributes to project-wide analytics without PII
|
||||
|
||||
### API Communication Errors
|
||||
- **Network Failures**: Handle API communication failures gracefully
|
||||
- **Missing Prerequisites**: Check prerequisites before API calls
|
||||
- **Duplicate Prevention**: Prevent duplicate status updates
|
||||
- **Error Recovery**: Handle API errors without blocking installation
|
||||
- **Network Failures**: All API calls use `|| true` — failures are swallowed silently
|
||||
- **Missing Prerequisites**: Functions return early if curl, DIAGNOSTICS, or UUID are missing
|
||||
- **Duplicate Prevention**: `POST_UPDATE_DONE` flag ensures only one PATCH per session
|
||||
- **Record Lookup Fallback**: If `PB_RECORD_ID` is unset, a GET filter query resolves the record
|
||||
|
||||
## Performance Considerations
|
||||
|
||||
### API Communication Overhead
|
||||
- **Minimal Impact**: API calls add minimal overhead
|
||||
- **Asynchronous**: API calls don't block installation process
|
||||
- **Error Handling**: API failures don't affect installation
|
||||
- **Optional**: API reporting is optional and can be disabled
|
||||
- **Minimal Impact**: Only 2 HTTP calls per installation (1 POST + 1 PATCH)
|
||||
- **Non-blocking**: API failures never block the installation process
|
||||
- **Fire-and-forget**: curl stderr is suppressed (`2>/dev/null`)
|
||||
- **Optional**: Telemetry is entirely opt-in via `DIAGNOSTICS` setting
|
||||
|
||||
### Memory Usage
|
||||
- **Minimal Footprint**: API functions use minimal memory
|
||||
- **Variable Reuse**: Global variables reused across functions
|
||||
- **No Memory Leaks**: Proper cleanup prevents memory leaks
|
||||
- **Efficient Processing**: Efficient JSON payload creation
|
||||
|
||||
### Execution Speed
|
||||
- **Fast API Calls**: Quick API communication
|
||||
- **Efficient Error Processing**: Fast error code processing
|
||||
- **Minimal Delay**: Minimal delay in API operations
|
||||
- **Non-blocking**: API calls don't block installation
|
||||
|
||||
## Security Considerations
|
||||
|
||||
### Data Privacy
|
||||
- **Anonymous Reporting**: Only anonymous data is sent
|
||||
- **No Sensitive Data**: No sensitive information is transmitted
|
||||
- **User Control**: Users can disable diagnostic reporting
|
||||
- **Data Minimization**: Only necessary data is sent
|
||||
|
||||
### API Security
|
||||
- **HTTPS**: API communication uses secure protocols
|
||||
- **Data Validation**: API data is validated before sending
|
||||
- **Error Handling**: API errors are handled securely
|
||||
- **No Credentials**: No authentication credentials are sent
|
||||
|
||||
### Network Security
|
||||
- **Secure Communication**: Uses secure HTTP protocols
|
||||
- **Error Handling**: Network errors are handled gracefully
|
||||
- **No Data Leakage**: No sensitive data is leaked
|
||||
- **Secure Endpoints**: Uses trusted API endpoints
|
||||
|
||||
## Future Integration Considerations
|
||||
|
||||
### Extensibility
|
||||
- **New API Endpoints**: Easy to add new API endpoints
|
||||
- **Additional Data**: Easy to add new data fields
|
||||
- **Error Codes**: Easy to add new error code descriptions
|
||||
- **API Versions**: Easy to support new API versions
|
||||
|
||||
### Compatibility
|
||||
- **API Versioning**: Compatible with different API versions
|
||||
- **Data Format**: Compatible with different data formats
|
||||
- **Error Codes**: Compatible with different error code systems
|
||||
- **Network Protocols**: Compatible with different network protocols
|
||||
|
||||
### Performance
|
||||
- **Optimization**: API communication can be optimized
|
||||
- **Caching**: API responses can be cached
|
||||
- **Batch Operations**: Multiple operations can be batched
|
||||
- **Async Processing**: API calls can be made asynchronous
|
||||
### Security Considerations
|
||||
- **Anonymous**: No personal data is transmitted — only system specs and app names
|
||||
- **No Auth Required**: PocketBase collection rules allow anonymous create/update
|
||||
- **User Control**: Users can disable telemetry by setting `DIAGNOSTICS=no`
|
||||
- **HTTP**: API uses HTTP (not HTTPS) for compatibility with minimal containers
|
||||
|
||||
@@ -1,794 +0,0 @@
|
||||
# api.func Usage Examples
|
||||
|
||||
## Overview
|
||||
|
||||
This document provides practical usage examples for `api.func` functions, covering common scenarios, integration patterns, and best practices.
|
||||
|
||||
## Basic API Setup
|
||||
|
||||
### Standard API Initialization
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
# Standard API setup for LXC containers
|
||||
|
||||
source api.func
|
||||
|
||||
# Set up diagnostic reporting
|
||||
export DIAGNOSTICS="yes"
|
||||
export RANDOM_UUID="$(uuidgen)"
|
||||
|
||||
# Set container parameters
|
||||
export CT_TYPE=1
|
||||
export DISK_SIZE=8
|
||||
export CORE_COUNT=2
|
||||
export RAM_SIZE=2048
|
||||
export var_os="debian"
|
||||
export var_version="12"
|
||||
export NSAPP="plex"
|
||||
export METHOD="install"
|
||||
|
||||
# Report installation start
|
||||
post_to_api
|
||||
|
||||
# Your installation code here
|
||||
# ... installation logic ...
|
||||
|
||||
# Report completion
|
||||
if [[ $? -eq 0 ]]; then
|
||||
post_update_to_api "success" 0
|
||||
else
|
||||
post_update_to_api "failed" $?
|
||||
fi
|
||||
```
|
||||
|
||||
### VM API Setup
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
# API setup for VMs
|
||||
|
||||
source api.func
|
||||
|
||||
# Create diagnostics file for VM
|
||||
mkdir -p /usr/local/community-scripts
|
||||
echo "DIAGNOSTICS=yes" > /usr/local/community-scripts/diagnostics
|
||||
|
||||
# Set up VM parameters
|
||||
export RANDOM_UUID="$(uuidgen)"
|
||||
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"
|
||||
|
||||
# Report VM installation start
|
||||
post_to_api_vm
|
||||
|
||||
# Your VM installation code here
|
||||
# ... VM creation logic ...
|
||||
|
||||
# Report completion
|
||||
post_update_to_api "success" 0
|
||||
```
|
||||
|
||||
## Error Description Examples
|
||||
|
||||
### Basic Error Explanation
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
source api.func
|
||||
|
||||
# Explain common error codes
|
||||
echo "Error 0: '$(get_error_description 0)'"
|
||||
echo "Error 1: $(get_error_description 1)"
|
||||
echo "Error 127: $(get_error_description 127)"
|
||||
echo "Error 200: $(get_error_description 200)"
|
||||
echo "Error 255: $(get_error_description 255)"
|
||||
```
|
||||
|
||||
### Error Code Testing
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
source api.func
|
||||
|
||||
# Test all error codes
|
||||
test_error_codes() {
|
||||
local codes=(0 1 2 127 128 130 137 139 143 200 203 205 255)
|
||||
|
||||
for code in "${codes[@]}"; do
|
||||
echo "Code $code: $(get_error_description $code)"
|
||||
done
|
||||
}
|
||||
|
||||
test_error_codes
|
||||
```
|
||||
|
||||
### Error Handling with Descriptions
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
source api.func
|
||||
|
||||
# Function with error handling
|
||||
run_command_with_error_handling() {
|
||||
local command="$1"
|
||||
local description="$2"
|
||||
|
||||
echo "Running: $description"
|
||||
|
||||
if $command; then
|
||||
echo "Success: $description"
|
||||
return 0
|
||||
else
|
||||
local exit_code=$?
|
||||
local error_msg=$(get_error_description $exit_code)
|
||||
echo "Error $exit_code: $error_msg"
|
||||
return $exit_code
|
||||
fi
|
||||
}
|
||||
|
||||
# Usage
|
||||
run_command_with_error_handling "apt-get update" "Package list update"
|
||||
run_command_with_error_handling "nonexistent_command" "Test command"
|
||||
```
|
||||
|
||||
## API Communication Examples
|
||||
|
||||
### LXC Installation Reporting
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
source api.func
|
||||
|
||||
# Complete LXC installation with API reporting
|
||||
install_lxc_with_reporting() {
|
||||
local app="$1"
|
||||
local ctid="$2"
|
||||
|
||||
# Set up API reporting
|
||||
export DIAGNOSTICS="yes"
|
||||
export RANDOM_UUID="$(uuidgen)"
|
||||
export CT_TYPE=1
|
||||
export DISK_SIZE=10
|
||||
export CORE_COUNT=2
|
||||
export RAM_SIZE=2048
|
||||
export var_os="debian"
|
||||
export var_version="12"
|
||||
export NSAPP="$app"
|
||||
export METHOD="install"
|
||||
|
||||
# Report installation start
|
||||
post_to_api
|
||||
|
||||
# Installation process
|
||||
echo "Installing $app container (ID: $ctid)..."
|
||||
|
||||
# Simulate installation
|
||||
sleep 2
|
||||
|
||||
# Check if installation succeeded
|
||||
if [[ $? -eq 0 ]]; then
|
||||
echo "Installation completed successfully"
|
||||
post_update_to_api "success" 0
|
||||
return 0
|
||||
else
|
||||
echo "Installation failed"
|
||||
post_update_to_api "failed" $?
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Install multiple containers
|
||||
install_lxc_with_reporting "plex" "100"
|
||||
install_lxc_with_reporting "nextcloud" "101"
|
||||
install_lxc_with_reporting "nginx" "102"
|
||||
```
|
||||
|
||||
### VM Installation Reporting
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
source api.func
|
||||
|
||||
# Complete VM installation with API reporting
|
||||
install_vm_with_reporting() {
|
||||
local app="$1"
|
||||
local vmid="$2"
|
||||
|
||||
# Create diagnostics file
|
||||
mkdir -p /usr/local/community-scripts
|
||||
echo "DIAGNOSTICS=yes" > /usr/local/community-scripts/diagnostics
|
||||
|
||||
# Set up API reporting
|
||||
export RANDOM_UUID="$(uuidgen)"
|
||||
export DISK_SIZE="20G"
|
||||
export CORE_COUNT=4
|
||||
export RAM_SIZE=4096
|
||||
export var_os="ubuntu"
|
||||
export var_version="22.04"
|
||||
export NSAPP="$app"
|
||||
export METHOD="install"
|
||||
|
||||
# Report VM installation start
|
||||
post_to_api_vm
|
||||
|
||||
# VM installation process
|
||||
echo "Installing $app VM (ID: $vmid)..."
|
||||
|
||||
# Simulate VM creation
|
||||
sleep 3
|
||||
|
||||
# Check if VM creation succeeded
|
||||
if [[ $? -eq 0 ]]; then
|
||||
echo "VM installation completed successfully"
|
||||
post_update_to_api "success" 0
|
||||
return 0
|
||||
else
|
||||
echo "VM installation failed"
|
||||
post_update_to_api "failed" $?
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Install multiple VMs
|
||||
install_vm_with_reporting "nextcloud" "200"
|
||||
install_vm_with_reporting "wordpress" "201"
|
||||
```
|
||||
|
||||
## Status Update Examples
|
||||
|
||||
### Success Reporting
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
source api.func
|
||||
|
||||
# Report successful installation
|
||||
report_success() {
|
||||
local operation="$1"
|
||||
|
||||
export DIAGNOSTICS="yes"
|
||||
export RANDOM_UUID="$(uuidgen)"
|
||||
|
||||
echo "Reporting successful $operation"
|
||||
post_update_to_api "success" 0
|
||||
}
|
||||
|
||||
# Usage
|
||||
report_success "container installation"
|
||||
report_success "package installation"
|
||||
report_success "service configuration"
|
||||
```
|
||||
|
||||
### Failure Reporting
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
source api.func
|
||||
|
||||
# Report failed installation
|
||||
report_failure() {
|
||||
local operation="$1"
|
||||
local exit_code="$2"
|
||||
|
||||
export DIAGNOSTICS="yes"
|
||||
export RANDOM_UUID="$(uuidgen)"
|
||||
|
||||
local error_msg=$(get_error_description $exit_code)
|
||||
echo "Reporting failed $operation: $error_msg"
|
||||
post_update_to_api "failed" $exit_code
|
||||
}
|
||||
|
||||
# Usage
|
||||
report_failure "container creation" 200
|
||||
report_failure "package installation" 127
|
||||
report_failure "service start" 1
|
||||
```
|
||||
|
||||
### Conditional Status Reporting
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
source api.func
|
||||
|
||||
# Conditional status reporting
|
||||
report_installation_status() {
|
||||
local operation="$1"
|
||||
local exit_code="$2"
|
||||
|
||||
export DIAGNOSTICS="yes"
|
||||
export RANDOM_UUID="$(uuidgen)"
|
||||
|
||||
if [[ $exit_code -eq 0 ]]; then
|
||||
echo "Reporting successful $operation"
|
||||
post_update_to_api "success" 0
|
||||
else
|
||||
local error_msg=$(get_error_description $exit_code)
|
||||
echo "Reporting failed $operation: $error_msg"
|
||||
post_update_to_api "failed" $exit_code
|
||||
fi
|
||||
}
|
||||
|
||||
# Usage
|
||||
report_installation_status "container creation" 0
|
||||
report_installation_status "package installation" 127
|
||||
```
|
||||
|
||||
## Advanced Usage Examples
|
||||
|
||||
### Batch Installation with API Reporting
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
source api.func
|
||||
|
||||
# Batch installation with comprehensive API reporting
|
||||
batch_install_with_reporting() {
|
||||
local apps=("plex" "nextcloud" "nginx" "mysql")
|
||||
local ctids=(100 101 102 103)
|
||||
|
||||
# Set up API reporting
|
||||
export DIAGNOSTICS="yes"
|
||||
export RANDOM_UUID="$(uuidgen)"
|
||||
export CT_TYPE=1
|
||||
export DISK_SIZE=8
|
||||
export CORE_COUNT=2
|
||||
export RAM_SIZE=2048
|
||||
export var_os="debian"
|
||||
export var_version="12"
|
||||
export METHOD="install"
|
||||
|
||||
local success_count=0
|
||||
local failure_count=0
|
||||
|
||||
for i in "${!apps[@]}"; do
|
||||
local app="${apps[$i]}"
|
||||
local ctid="${ctids[$i]}"
|
||||
|
||||
echo "Installing $app (ID: $ctid)..."
|
||||
|
||||
# Set app-specific parameters
|
||||
export NSAPP="$app"
|
||||
|
||||
# Report installation start
|
||||
post_to_api
|
||||
|
||||
# Simulate installation
|
||||
if install_app "$app" "$ctid"; then
|
||||
echo "$app installed successfully"
|
||||
post_update_to_api "success" 0
|
||||
((success_count++))
|
||||
else
|
||||
echo "$app installation failed"
|
||||
post_update_to_api "failed" $?
|
||||
((failure_count++))
|
||||
fi
|
||||
|
||||
echo "---"
|
||||
done
|
||||
|
||||
echo "Batch installation completed: $success_count successful, $failure_count failed"
|
||||
}
|
||||
|
||||
# Mock installation function
|
||||
install_app() {
|
||||
local app="$1"
|
||||
local ctid="$2"
|
||||
|
||||
# Simulate installation
|
||||
sleep 1
|
||||
|
||||
# Simulate occasional failures
|
||||
if [[ $((RANDOM % 10)) -eq 0 ]]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
batch_install_with_reporting
|
||||
```
|
||||
|
||||
### Error Analysis and Reporting
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
source api.func
|
||||
|
||||
# Analyze and report errors
|
||||
analyze_and_report_errors() {
|
||||
local log_file="$1"
|
||||
|
||||
export DIAGNOSTICS="yes"
|
||||
export RANDOM_UUID="$(uuidgen)"
|
||||
|
||||
if [[ ! -f "$log_file" ]]; then
|
||||
echo "Log file not found: $log_file"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Extract error codes from log
|
||||
local error_codes=$(grep -o 'exit code [0-9]\+' "$log_file" | grep -o '[0-9]\+' | sort -u)
|
||||
|
||||
if [[ -z "$error_codes" ]]; then
|
||||
echo "No errors found in log"
|
||||
post_update_to_api "success" 0
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo "Found error codes: $error_codes"
|
||||
|
||||
# Report each unique error
|
||||
for code in $error_codes; do
|
||||
local error_msg=$(get_error_description $code)
|
||||
echo "Error $code: $error_msg"
|
||||
post_update_to_api "failed" $code
|
||||
done
|
||||
}
|
||||
|
||||
# Usage
|
||||
analyze_and_report_errors "/var/log/installation.log"
|
||||
```
|
||||
|
||||
### API Health Check
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
source api.func
|
||||
|
||||
# Check API connectivity and functionality
|
||||
check_api_health() {
|
||||
echo "Checking API health..."
|
||||
|
||||
# Test prerequisites
|
||||
if ! command -v curl >/dev/null 2>&1; then
|
||||
echo "ERROR: curl not available"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Test error description function
|
||||
local test_error=$(get_error_description 127)
|
||||
if [[ -z "$test_error" ]]; then
|
||||
echo "ERROR: Error description function not working"
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo "Error description test: $test_error"
|
||||
|
||||
# Test API connectivity (without sending data)
|
||||
local api_url="http://api.community-scripts.org/dev/upload"
|
||||
if curl -s --head "$api_url" >/dev/null 2>&1; then
|
||||
echo "API endpoint is reachable"
|
||||
else
|
||||
echo "WARNING: API endpoint not reachable"
|
||||
fi
|
||||
|
||||
echo "API health check completed"
|
||||
}
|
||||
|
||||
check_api_health
|
||||
```
|
||||
|
||||
## Integration Examples
|
||||
|
||||
### With build.func
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
# Integration with build.func
|
||||
|
||||
source core.func
|
||||
source api.func
|
||||
source build.func
|
||||
|
||||
# Set up API reporting
|
||||
export DIAGNOSTICS="yes"
|
||||
export RANDOM_UUID="$(uuidgen)"
|
||||
|
||||
# Container creation with API reporting
|
||||
create_container_with_reporting() {
|
||||
local app="$1"
|
||||
local ctid="$2"
|
||||
|
||||
# Set container parameters
|
||||
export APP="$app"
|
||||
export CTID="$ctid"
|
||||
export var_hostname="${app}-server"
|
||||
export var_os="debian"
|
||||
export var_version="12"
|
||||
export var_cpu="2"
|
||||
export var_ram="2048"
|
||||
export var_disk="10"
|
||||
export var_net="vmbr0"
|
||||
export var_gateway="192.168.1.1"
|
||||
export var_ip="192.168.1.$ctid"
|
||||
export var_template_storage="local"
|
||||
export var_container_storage="local"
|
||||
|
||||
# Report installation start
|
||||
post_to_api
|
||||
|
||||
# Create container using build.func
|
||||
if source build.func; then
|
||||
echo "Container $app created successfully"
|
||||
post_update_to_api "success" 0
|
||||
return 0
|
||||
else
|
||||
echo "Container $app creation failed"
|
||||
post_update_to_api "failed" $?
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Create containers
|
||||
create_container_with_reporting "plex" "100"
|
||||
create_container_with_reporting "nextcloud" "101"
|
||||
```
|
||||
|
||||
### With vm-core.func
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
# Integration with vm-core.func
|
||||
|
||||
source core.func
|
||||
source api.func
|
||||
source vm-core.func
|
||||
|
||||
# Set up VM API reporting
|
||||
mkdir -p /usr/local/community-scripts
|
||||
echo "DIAGNOSTICS=yes" > /usr/local/community-scripts/diagnostics
|
||||
|
||||
export RANDOM_UUID="$(uuidgen)"
|
||||
|
||||
# VM creation with API reporting
|
||||
create_vm_with_reporting() {
|
||||
local app="$1"
|
||||
local vmid="$2"
|
||||
|
||||
# Set VM parameters
|
||||
export APP="$app"
|
||||
export VMID="$vmid"
|
||||
export var_hostname="${app}-vm"
|
||||
export var_os="ubuntu"
|
||||
export var_version="22.04"
|
||||
export var_cpu="4"
|
||||
export var_ram="4096"
|
||||
export var_disk="20"
|
||||
|
||||
# Report VM installation start
|
||||
post_to_api_vm
|
||||
|
||||
# Create VM using vm-core.func
|
||||
if source vm-core.func; then
|
||||
echo "VM $app created successfully"
|
||||
post_update_to_api "success" 0
|
||||
return 0
|
||||
else
|
||||
echo "VM $app creation failed"
|
||||
post_update_to_api "failed" $?
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Create VMs
|
||||
create_vm_with_reporting "nextcloud" "200"
|
||||
create_vm_with_reporting "wordpress" "201"
|
||||
```
|
||||
|
||||
### With error_handler.func
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
# Integration with error_handler.func
|
||||
|
||||
source core.func
|
||||
source error_handler.func
|
||||
source api.func
|
||||
|
||||
# Enhanced error handling with API reporting
|
||||
enhanced_error_handler() {
|
||||
local exit_code=${1:-$?}
|
||||
local command=${2:-${BASH_COMMAND:-unknown}}
|
||||
|
||||
# Get error description from api.func
|
||||
local error_msg=$(get_error_description $exit_code)
|
||||
|
||||
# Display error information
|
||||
echo "Error $exit_code: $error_msg"
|
||||
echo "Command: $command"
|
||||
|
||||
# Report error to API
|
||||
export DIAGNOSTICS="yes"
|
||||
export RANDOM_UUID="$(uuidgen)"
|
||||
post_update_to_api "failed" $exit_code
|
||||
|
||||
# Use standard error handler
|
||||
error_handler $exit_code $command
|
||||
}
|
||||
|
||||
# Set up enhanced error handling
|
||||
trap 'enhanced_error_handler' ERR
|
||||
|
||||
# Test enhanced error handling
|
||||
nonexistent_command
|
||||
```
|
||||
|
||||
## Best Practices Examples
|
||||
|
||||
### Comprehensive API Integration
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
# Comprehensive API integration example
|
||||
|
||||
source core.func
|
||||
source api.func
|
||||
|
||||
# Set up comprehensive API reporting
|
||||
setup_api_reporting() {
|
||||
# Enable diagnostics
|
||||
export DIAGNOSTICS="yes"
|
||||
export RANDOM_UUID="$(uuidgen)"
|
||||
|
||||
# Set common parameters
|
||||
export CT_TYPE=1
|
||||
export DISK_SIZE=8
|
||||
export CORE_COUNT=2
|
||||
export RAM_SIZE=2048
|
||||
export var_os="debian"
|
||||
export var_version="12"
|
||||
export METHOD="install"
|
||||
|
||||
echo "API reporting configured"
|
||||
}
|
||||
|
||||
# Installation with comprehensive reporting
|
||||
install_with_comprehensive_reporting() {
|
||||
local app="$1"
|
||||
local ctid="$2"
|
||||
|
||||
# Set up API reporting
|
||||
setup_api_reporting
|
||||
export NSAPP="$app"
|
||||
|
||||
# Report installation start
|
||||
post_to_api
|
||||
|
||||
# Installation process
|
||||
echo "Installing $app..."
|
||||
|
||||
# Simulate installation steps
|
||||
local steps=("Downloading" "Installing" "Configuring" "Starting")
|
||||
for step in "${steps[@]}"; do
|
||||
echo "$step $app..."
|
||||
sleep 1
|
||||
done
|
||||
|
||||
# Check installation result
|
||||
if [[ $? -eq 0 ]]; then
|
||||
echo "$app installation completed successfully"
|
||||
post_update_to_api "success" 0
|
||||
return 0
|
||||
else
|
||||
echo "$app installation failed"
|
||||
post_update_to_api "failed" $?
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Install multiple applications
|
||||
apps=("plex" "nextcloud" "nginx" "mysql")
|
||||
ctids=(100 101 102 103)
|
||||
|
||||
for i in "${!apps[@]}"; do
|
||||
install_with_comprehensive_reporting "${apps[$i]}" "${ctids[$i]}"
|
||||
echo "---"
|
||||
done
|
||||
```
|
||||
|
||||
### Error Recovery with API Reporting
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
source api.func
|
||||
|
||||
# Error recovery with API reporting
|
||||
retry_with_api_reporting() {
|
||||
local operation="$1"
|
||||
local max_attempts=3
|
||||
local attempt=1
|
||||
|
||||
export DIAGNOSTICS="yes"
|
||||
export RANDOM_UUID="$(uuidgen)"
|
||||
|
||||
while [[ $attempt -le $max_attempts ]]; do
|
||||
echo "Attempt $attempt of $max_attempts: $operation"
|
||||
|
||||
if $operation; then
|
||||
echo "Operation succeeded on attempt $attempt"
|
||||
post_update_to_api "success" 0
|
||||
return 0
|
||||
else
|
||||
local exit_code=$?
|
||||
local error_msg=$(get_error_description $exit_code)
|
||||
echo "Attempt $attempt failed: $error_msg"
|
||||
|
||||
post_update_to_api "failed" $exit_code
|
||||
|
||||
((attempt++))
|
||||
|
||||
if [[ $attempt -le $max_attempts ]]; then
|
||||
echo "Retrying in 5 seconds..."
|
||||
sleep 5
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
echo "Operation failed after $max_attempts attempts"
|
||||
return 1
|
||||
}
|
||||
|
||||
# Usage
|
||||
retry_with_api_reporting "apt-get update"
|
||||
retry_with_api_reporting "apt-get install -y package"
|
||||
```
|
||||
|
||||
### API Reporting with Logging
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
source api.func
|
||||
|
||||
# API reporting with detailed logging
|
||||
install_with_logging_and_api() {
|
||||
local app="$1"
|
||||
local log_file="/var/log/${app}_installation.log"
|
||||
|
||||
# Set up API reporting
|
||||
export DIAGNOSTICS="yes"
|
||||
export RANDOM_UUID="$(uuidgen)"
|
||||
export NSAPP="$app"
|
||||
|
||||
# Start logging
|
||||
exec > >(tee -a "$log_file")
|
||||
exec 2>&1
|
||||
|
||||
echo "Starting $app installation at $(date)"
|
||||
|
||||
# Report installation start
|
||||
post_to_api
|
||||
|
||||
# Installation process
|
||||
echo "Installing $app..."
|
||||
|
||||
# Simulate installation
|
||||
if install_app "$app"; then
|
||||
echo "$app installation completed successfully at $(date)"
|
||||
post_update_to_api "success" 0
|
||||
return 0
|
||||
else
|
||||
local exit_code=$?
|
||||
local error_msg=$(get_error_description $exit_code)
|
||||
echo "$app installation failed at $(date): $error_msg"
|
||||
post_update_to_api "failed" $exit_code
|
||||
return $exit_code
|
||||
fi
|
||||
}
|
||||
|
||||
# Mock installation function
|
||||
install_app() {
|
||||
local app="$1"
|
||||
echo "Installing $app..."
|
||||
sleep 2
|
||||
return 0
|
||||
}
|
||||
|
||||
# Install with logging and API reporting
|
||||
install_with_logging_and_api "plex"
|
||||
```
|
||||
@@ -2,22 +2,27 @@
|
||||
|
||||
## Overview
|
||||
|
||||
The `api.func` file provides Proxmox API integration and diagnostic reporting functionality for the Community Scripts project. It handles API communication, error reporting, and status updates to the community-scripts.org API.
|
||||
The `api.func` file provides PocketBase API integration and diagnostic reporting for the Community Scripts project. It handles telemetry communication, error reporting, and status updates to the PocketBase backend at `db.community-scripts.org`.
|
||||
|
||||
## Purpose and Use Cases
|
||||
|
||||
- **API Communication**: Send installation and status data to community-scripts.org API
|
||||
- **API Communication**: Send installation and status data to PocketBase
|
||||
- **Diagnostic Reporting**: Report installation progress and errors for analytics
|
||||
- **Error Description**: Provide detailed error code explanations
|
||||
- **Error Description**: Provide detailed error code explanations (canonical source of truth)
|
||||
- **Status Updates**: Track installation success/failure status
|
||||
- **Analytics**: Contribute anonymous usage data for project improvement
|
||||
|
||||
## Quick Reference
|
||||
|
||||
### Key Function Groups
|
||||
- **Error Handling**: `get_error_description()` - Convert exit codes to human-readable messages
|
||||
- **API Communication**: `post_to_api()`, `post_to_api_vm()` - Send installation data
|
||||
- **Status Updates**: `post_update_to_api()` - Report installation completion status
|
||||
- **Error Handling**: `explain_exit_code()` - Convert exit codes to human-readable messages
|
||||
- **API Communication**: `post_to_api()`, `post_to_api_vm()` - Send installation data to PocketBase
|
||||
- **Status Updates**: `post_update_to_api()` - Report installation completion status via PATCH
|
||||
|
||||
### PocketBase Configuration
|
||||
- **URL**: `http://db.community-scripts.org`
|
||||
- **Collection**: `_dev_telemetry_data`
|
||||
- **API Endpoint**: `/api/collections/_dev_telemetry_data/records`
|
||||
|
||||
### Dependencies
|
||||
- **External**: `curl` command for HTTP requests
|
||||
@@ -26,7 +31,7 @@ The `api.func` file provides Proxmox API integration and diagnostic reporting fu
|
||||
### Integration Points
|
||||
- Used by: All installation scripts for diagnostic reporting
|
||||
- Uses: Environment variables from build.func and other scripts
|
||||
- Provides: API communication and error reporting services
|
||||
- Provides: API communication, error reporting, and exit code descriptions
|
||||
|
||||
## Documentation Files
|
||||
|
||||
@@ -44,17 +49,18 @@ How api.func integrates with other components and provides API services.
|
||||
|
||||
## Key Features
|
||||
|
||||
### Error Code Descriptions
|
||||
- **Comprehensive Coverage**: 50+ error codes with detailed explanations
|
||||
- **LXC-Specific Errors**: Container creation and management errors
|
||||
- **System Errors**: General system and network errors
|
||||
### Exit Code Descriptions
|
||||
- **Canonical source**: Single authoritative `explain_exit_code()` for the entire project
|
||||
- **Non-overlapping ranges**: Clean separation between error categories
|
||||
- **Comprehensive Coverage**: 60+ error codes with detailed explanations
|
||||
- **System Errors**: General system, curl, and network errors
|
||||
- **Signal Errors**: Process termination and signal errors
|
||||
|
||||
### API Communication
|
||||
- **LXC Reporting**: Send LXC container installation data
|
||||
- **VM Reporting**: Send VM installation data
|
||||
- **Status Updates**: Report installation success/failure
|
||||
- **Diagnostic Data**: Anonymous usage analytics
|
||||
### PocketBase Integration
|
||||
- **Record Creation**: POST to create telemetry records with status `installing`
|
||||
- **Record Updates**: PATCH to update with final status, exit code, and error
|
||||
- **ID Tracking**: Stores `PB_RECORD_ID` for efficient updates
|
||||
- **Fallback Lookup**: Searches by `random_id` filter if record ID is lost
|
||||
|
||||
### Diagnostic Integration
|
||||
- **Optional Reporting**: Only sends data when diagnostics enabled
|
||||
@@ -67,15 +73,13 @@ How api.func integrates with other components and provides API services.
|
||||
### Basic API Setup
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
# Basic API setup
|
||||
|
||||
source api.func
|
||||
|
||||
# Set up diagnostic reporting
|
||||
export DIAGNOSTICS="yes"
|
||||
export RANDOM_UUID="$(uuidgen)"
|
||||
export RANDOM_UUID="$(cat /proc/sys/kernel/random/uuid)"
|
||||
|
||||
# Report installation start
|
||||
# Report installation start (creates PocketBase record)
|
||||
post_to_api
|
||||
```
|
||||
|
||||
@@ -85,9 +89,9 @@ post_to_api
|
||||
source api.func
|
||||
|
||||
# Get error description
|
||||
error_msg=$(get_error_description 127)
|
||||
echo "Error 127: $error_msg"
|
||||
# Output: Error 127: Command not found: Incorrect path or missing dependency.
|
||||
error_msg=$(explain_exit_code 137)
|
||||
echo "Error 137: $error_msg"
|
||||
# Output: Error 137: Killed (SIGKILL / Out of memory?)
|
||||
```
|
||||
|
||||
### Status Updates
|
||||
@@ -96,9 +100,9 @@ echo "Error 127: $error_msg"
|
||||
source api.func
|
||||
|
||||
# Report successful installation
|
||||
post_update_to_api "success" 0
|
||||
post_update_to_api "done" 0
|
||||
|
||||
# Report failed installation
|
||||
# Report failed installation with exit code
|
||||
post_update_to_api "failed" 127
|
||||
```
|
||||
|
||||
@@ -106,7 +110,7 @@ post_update_to_api "failed" 127
|
||||
|
||||
### Required Variables
|
||||
- `DIAGNOSTICS`: Enable/disable diagnostic reporting ("yes"/"no")
|
||||
- `RANDOM_UUID`: Unique identifier for tracking
|
||||
- `RANDOM_UUID`: Unique identifier for session tracking
|
||||
|
||||
### Optional Variables
|
||||
- `CT_TYPE`: Container type (1 for LXC, 2 for VM)
|
||||
@@ -115,33 +119,31 @@ post_update_to_api "failed" 127
|
||||
- `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
|
||||
- `PB_URL`: PocketBase base URL
|
||||
- `PB_API_URL`: Full API endpoint URL
|
||||
- `PB_RECORD_ID`: Stored PocketBase record ID for updates
|
||||
|
||||
## Error Code Categories
|
||||
## Error Code Categories (Non-Overlapping Ranges)
|
||||
|
||||
### General System Errors
|
||||
- **0-9**: Basic system errors
|
||||
- **18, 22, 28, 35**: Network and I/O errors
|
||||
- **56, 60**: TLS/SSL errors
|
||||
- **125-128**: Command execution errors
|
||||
- **129-143**: Signal errors
|
||||
- **152**: Resource limit errors
|
||||
- **255**: Unknown critical errors
|
||||
|
||||
### LXC-Specific Errors
|
||||
- **100-101**: LXC installation errors
|
||||
- **200-209**: LXC creation and management errors
|
||||
|
||||
### Docker Errors
|
||||
- **125**: Docker container start errors
|
||||
| Range | Category |
|
||||
|-------|----------|
|
||||
| 1-2 | Generic shell errors |
|
||||
| 6-35 | curl/wget network errors |
|
||||
| 100-102 | APT/DPKG package errors |
|
||||
| 124-143 | Command execution & signal errors |
|
||||
| 150-154 | Systemd/service errors |
|
||||
| 160-162 | Python/pip/uv errors |
|
||||
| 170-173 | PostgreSQL errors |
|
||||
| 180-183 | MySQL/MariaDB errors |
|
||||
| 190-193 | MongoDB errors |
|
||||
| 200-231 | Proxmox custom codes |
|
||||
| 243-249 | Node.js/npm errors |
|
||||
| 255 | DPKG fatal error |
|
||||
|
||||
## Best Practices
|
||||
|
||||
@@ -152,48 +154,56 @@ post_update_to_api "failed" 127
|
||||
4. Report both success and failure cases
|
||||
|
||||
### Error Handling
|
||||
1. Use appropriate error codes
|
||||
2. Provide meaningful error descriptions
|
||||
1. Use the correct non-overlapping exit code ranges
|
||||
2. Use `explain_exit_code()` from api.func (canonical source)
|
||||
3. Handle API communication failures gracefully
|
||||
4. Don't block installation on API failures
|
||||
|
||||
### API Usage
|
||||
1. Check for curl availability
|
||||
2. Handle network failures gracefully
|
||||
3. Use appropriate HTTP methods
|
||||
4. Include all required data
|
||||
1. Check for curl availability before API calls
|
||||
2. Handle network failures gracefully (all calls use `|| true`)
|
||||
3. Store and reuse PB_RECORD_ID for updates
|
||||
4. Use proper PocketBase REST methods (POST for create, PATCH for update)
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
1. **API Communication Fails**: Check network connectivity and curl availability
|
||||
2. **Diagnostics Not Working**: Verify DIAGNOSTICS setting and RANDOM_UUID
|
||||
3. **Missing Error Descriptions**: Check error code coverage
|
||||
4. **Duplicate Updates**: POST_UPDATE_DONE prevents duplicates
|
||||
2. **Diagnostics Not Working**: Verify `DIAGNOSTICS=yes` in `/usr/local/community-scripts/diagnostics`
|
||||
3. **Status Update Fails**: Check that `PB_RECORD_ID` was captured or `random_id` filter works
|
||||
4. **Duplicate Updates**: `POST_UPDATE_DONE` flag prevents duplicates
|
||||
|
||||
### Debug Mode
|
||||
Enable diagnostic reporting for debugging:
|
||||
```bash
|
||||
export DIAGNOSTICS="yes"
|
||||
export RANDOM_UUID="$(uuidgen)"
|
||||
export RANDOM_UUID="$(cat /proc/sys/kernel/random/uuid)"
|
||||
```
|
||||
|
||||
### API Testing
|
||||
Test API communication:
|
||||
Test PocketBase connectivity:
|
||||
```bash
|
||||
curl -s http://db.community-scripts.org/api/health
|
||||
```
|
||||
|
||||
Test record creation:
|
||||
```bash
|
||||
source api.func
|
||||
export DIAGNOSTICS="yes"
|
||||
export RANDOM_UUID="test-$(date +%s)"
|
||||
export NSAPP="test"
|
||||
export CT_TYPE=1
|
||||
post_to_api
|
||||
echo "Record ID: $PB_RECORD_ID"
|
||||
```
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- [core.func](../core.func/) - Core utilities and error handling
|
||||
- [error_handler.func](../error_handler.func/) - Error handling utilities
|
||||
- [core.func](../core.func/) - Core utilities
|
||||
- [error_handler.func](../error_handler.func/) - Error handling (fallback `explain_exit_code`)
|
||||
- [build.func](../build.func/) - Container creation with API integration
|
||||
- [tools.func](../tools.func/) - Extended utilities with API integration
|
||||
- [tools.func](../tools.func/) - Extended utilities
|
||||
|
||||
---
|
||||
|
||||
*This documentation covers the api.func file which provides API communication and diagnostic reporting for all Proxmox Community Scripts.*
|
||||
*This documentation covers the api.func file which provides PocketBase communication and diagnostic reporting for all Proxmox Community Scripts.*
|
||||
|
||||
Reference in New Issue
Block a user