ProxmoxVED/docs/misc/api.func/API_INTEGRATION.md
CanbiZ (MickLesk) 820d4551a1 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.
2026-02-09 15:34:17 +01:00

11 KiB

api.func Integration Guide

Overview

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 PocketBase API communication

Optional Commands

  • 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 (CT_TYPE, DISK_SIZE, etc.)
  • vm-core.func: Provides VM creation variables
  • core.func: Provides system information
  • Installation scripts: Provide application-specific variables (NSAPP, METHOD)

Integration Points

With build.func

LXC Container Reporting

source core.func
source api.func
source build.func

export DIAGNOSTICS="yes"
export RANDOM_UUID="$(uuidgen)"

# 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"

# POST → creates record in PocketBase, saves PB_RECORD_ID
post_to_api

# ... container creation via build.func ...

# 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

handle_container_error() {
    local exit_code=$1
    local error_msg=$(explain_exit_code $exit_code)

    echo "Container creation failed: $error_msg"
    post_update_to_api "failed" $exit_code
}

With vm-core.func

VM Installation Reporting

source core.func
source api.func
source vm-core.func

# VM reads DIAGNOSTICS from file
mkdir -p /usr/local/community-scripts
echo "DIAGNOSTICS=yes" > /usr/local/community-scripts/diagnostics

export RANDOM_UUID="$(uuidgen)"

# 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"

# POST → creates record in PocketBase (ct_type=2, type="vm")
post_to_api_vm

# ... VM creation via vm-core.func ...

# PATCH → finalizes record
post_update_to_api "done" 0

With error_handler.func

Error Description Integration

source core.func
source error_handler.func
source api.func

enhanced_error_handler() {
    local exit_code=${1:-$?}
    local command=${2:-${BASH_COMMAND:-unknown}}

    # explain_exit_code() is the canonical error description function
    local error_msg=$(explain_exit_code $exit_code)

    echo "Error $exit_code: $error_msg"
    echo "Command: $command"

    # PATCH the telemetry record with failure details
    post_update_to_api "failed" $exit_code
}

With install.func

Installation Process Reporting

source core.func
source api.func
source install.func

install_package_with_reporting() {
    local package="$1"

    export DIAGNOSTICS="yes"
    export RANDOM_UUID="$(uuidgen)"
    export NSAPP="$package"
    export METHOD="install"

    # POST → create telemetry record
    post_to_api

    if install_package "$package"; then
        echo "$package installed successfully"
        post_update_to_api "done" 0
        return 0
    else
        local 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
    fi
}

Data Flow

Input Data

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 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 at runtime
  • Disk size: VM disk size is stripped of G suffix before sending

Processing

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)

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

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

Internal State

Variable Description
PB_RECORD_ID PocketBase record ID for PATCH calls
POST_UPDATE_DONE Flag preventing duplicate updates

API Surface

Public Functions

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

PocketBase Collection Schema

Collection: _dev_telemetry_data

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

Note

: The status field intentionally uses the spelling "sucess" (not "success").

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

Standard Integration Pattern

#!/usr/bin/env bash

# 1. Source dependencies
source core.func
source api.func

# 2. Enable telemetry
export DIAGNOSTICS="yes"
export RANDOM_UUID="$(uuidgen)"

# 3. Set application parameters
export NSAPP="$APP"
export METHOD="install"

# 4. POST → create telemetry record in PocketBase
post_to_api

# 5. Perform installation
# ... installation logic ...

# 6. PATCH → update record with final status
post_update_to_api "done" 0

Minimal Integration Pattern

#!/usr/bin/env bash
source api.func

export DIAGNOSTICS="yes"
export RANDOM_UUID="$(uuidgen)"

# Report failure (PATCH via record lookup)
post_update_to_api "failed" 127

Advanced Integration Pattern

#!/usr/bin/env bash
source core.func
source api.func
source error_handler.func

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"

# Enhanced error handler with PocketBase reporting
enhanced_error_handler() {
    local exit_code=${1:-$?}
    local command=${2:-${BASH_COMMAND:-unknown}}

    local error_msg=$(explain_exit_code $exit_code)
    echo "Error $exit_code: $error_msg"

    post_update_to_api "failed" $exit_code
    error_handler $exit_code $command
}

trap 'enhanced_error_handler' ERR

# POST → create record
post_to_api

# ... operations ...

# PATCH → finalize
post_update_to_api "done" 0

Error Handling Integration

Automatic Error Reporting

  • 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: 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: 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

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