diff --git a/docs/DEFAULTS_SYSTEM_GUIDE.md b/docs/DEFAULTS_SYSTEM_GUIDE.md new file mode 100644 index 000000000..724798515 --- /dev/null +++ b/docs/DEFAULTS_SYSTEM_GUIDE.md @@ -0,0 +1,748 @@ +# Configuration & Defaults System - User Guide + +> **Complete Guide to App Defaults and User Defaults** +> +> *Learn how to configure, save, and reuse your installation settings* + +--- + +## Table of Contents + +1. [Quick Start](#quick-start) +2. [Understanding the Defaults System](#understanding-the-defaults-system) +3. [Installation Modes](#installation-modes) +4. [How to Save Defaults](#how-to-save-defaults) +5. [How to Use Saved Defaults](#how-to-use-saved-defaults) +6. [Managing Your Defaults](#managing-your-defaults) +7. [Advanced Configuration](#advanced-configuration) +8. [Troubleshooting](#troubleshooting) + +--- + +## Quick Start + +### 30-Second Setup + +```bash +# 1. Run any container installation script +bash pihole-install.sh + +# 2. When prompted, select: "Advanced Settings" +# (This allows you to customize everything) + +# 3. Answer all configuration questions + +# 4. At the end, when asked "Save as App Defaults?" +# Select: YES + +# 5. Done! Your settings are now saved +``` + +**Next Time**: Run the same script again, select **"App Defaults"** and your settings will be applied automatically! + +--- + +## Understanding the Defaults System + +### The Three-Tier System + +Your installation settings are managed through three layers: + +#### πŸ”· **Tier 1: Built-in Defaults** (Fallback) +``` +These are hardcoded in the scripts +Provide sensible defaults for each application +Example: PiHole uses 2 CPU cores by default +``` + +#### πŸ”Ά **Tier 2: User Defaults** (Global) +``` +Your personal global defaults +Applied to ALL container installations +Location: /usr/local/community-scripts/default.vars +Example: "I always want 4 CPU cores and 2GB RAM" +``` + +#### πŸ”΄ **Tier 3: App Defaults** (Specific) +``` +Application-specific saved settings +Only applied when installing that specific app +Location: /usr/local/community-scripts/defaults/.vars +Example: "Whenever I install PiHole, use these exact settings" +``` + +### Priority System + +When installing a container, settings are applied in this order: + +``` +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ 1. Environment Variables (HIGHEST) β”‚ Set in shell: export var_cpu=8 +β”‚ (these override everything) β”‚ +β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ +β”‚ 2. App Defaults β”‚ From: defaults/pihole.vars +β”‚ (app-specific saved settings) β”‚ +β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ +β”‚ 3. User Defaults β”‚ From: default.vars +β”‚ (your global defaults) β”‚ +β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ +β”‚ 4. Built-in Defaults (LOWEST) β”‚ Hardcoded in script +β”‚ (failsafe, always available) β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +``` + +**In Plain English**: +- If you set an environment variable β†’ it wins +- Otherwise, if you have app-specific defaults β†’ use those +- Otherwise, if you have user defaults β†’ use those +- Otherwise, use the hardcoded defaults + +--- + +## Installation Modes + +When you run any installation script, you'll be presented with a menu: + +### Option 1️⃣ : **Default Settings** + +``` +Quick installation with standard settings +β”œβ”€ Best for: First-time users, quick deployments +β”œβ”€ What happens: +β”‚ 1. Script uses built-in defaults +β”‚ 2. Container created immediately +β”‚ 3. No questions asked +└─ Time: ~2 minutes +``` + +**When to use**: You want a standard installation, don't need customization + +--- + +### Option 2️⃣ : **Advanced Settings** + +``` +Full customization with 19 configuration steps +β”œβ”€ Best for: Power users, custom requirements +β”œβ”€ What happens: +β”‚ 1. Script asks for EVERY setting +β”‚ 2. You control: CPU, RAM, Disk, Network, SSH, etc. +β”‚ 3. Shows summary before creating +β”‚ 4. Offers to save as App Defaults +└─ Time: ~5-10 minutes +``` + +**When to use**: You want full control over the configuration + +**Available Settings**: +- CPU cores, RAM amount, Disk size +- Container name, network settings +- SSH access, API access, Features +- Password, SSH keys, Tags + +--- + +### Option 3️⃣ : **User Defaults** + +``` +Use your saved global defaults +β”œβ”€ Best for: Consistent deployments across many containers +β”œβ”€ Requires: You've previously saved User Defaults +β”œβ”€ What happens: +β”‚ 1. Loads settings from: /usr/local/community-scripts/default.vars +β”‚ 2. Shows you the loaded settings +β”‚ 3. Creates container immediately +└─ Time: ~2 minutes +``` + +**When to use**: You have preferred defaults you want to use for every app + +--- + +### Option 4️⃣ : **App Defaults** (if available) + +``` +Use previously saved app-specific defaults +β”œβ”€ Best for: Repeating the same configuration multiple times +β”œβ”€ Requires: You've previously saved App Defaults for this app +β”œβ”€ What happens: +β”‚ 1. Loads settings from: /usr/local/community-scripts/defaults/.vars +β”‚ 2. Shows you the loaded settings +β”‚ 3. Creates container immediately +└─ Time: ~2 minutes +``` + +**When to use**: You've installed this app before and want identical settings + +--- + +### Option 5️⃣ : **Settings Menu** + +``` +Manage your saved configurations +β”œβ”€ Functions: +β”‚ β€’ View current settings +β”‚ β€’ Edit storage selections +β”‚ β€’ Manage defaults location +β”‚ β€’ See what's currently configured +└─ Time: ~1 minute +``` + +**When to use**: You want to review or modify saved settings + +--- + +## How to Save Defaults + +### Method 1: Save While Installing + +This is the easiest way: + +#### Step-by-Step: Create App Defaults + +```bash +# 1. Run the installation script +bash pihole-install.sh + +# 2. Choose installation mode +# β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +# β”‚ Select installation mode:β”‚ +# β”‚ 1) Default Settings β”‚ +# β”‚ 2) Advanced Settings β”‚ +# β”‚ 3) User Defaults β”‚ +# β”‚ 4) App Defaults β”‚ +# β”‚ 5) Settings Menu β”‚ +# β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +# +# Enter: 2 (Advanced Settings) + +# 3. Answer all configuration questions +# β€’ Container name? β†’ my-pihole +# β€’ CPU cores? β†’ 4 +# β€’ RAM amount? β†’ 2048 +# β€’ Disk size? β†’ 20 +# β€’ SSH access? β†’ yes +# ... (more options) + +# 4. Review summary (shown before creation) +# βœ“ Confirm to proceed + +# 5. After creation completes, you'll see: +# β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +# β”‚ Save as App Defaults for PiHole? β”‚ +# β”‚ (Yes/No) β”‚ +# β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +# +# Select: Yes + +# 6. Done! Settings saved to: +# /usr/local/community-scripts/defaults/pihole.vars +``` + +#### Step-by-Step: Create User Defaults + +```bash +# Same as App Defaults, but: +# When you select "Advanced Settings" +# FIRST app you run with this selection will offer +# to save as "User Defaults" additionally + +# This saves to: /usr/local/community-scripts/default.vars +``` + +--- + +### Method 2: Manual File Creation + +For advanced users who want to create defaults without running installation: + +```bash +# Create User Defaults manually +sudo tee /usr/local/community-scripts/default.vars > /dev/null << 'EOF' +# Global User Defaults +var_cpu=4 +var_ram=2048 +var_disk=20 +var_unprivileged=1 +var_brg=vmbr0 +var_gateway=192.168.1.1 +var_timezone=Europe/Berlin +var_ssh=yes +var_container_storage=local +var_template_storage=local +EOF + +# Create App Defaults manually +sudo tee /usr/local/community-scripts/defaults/pihole.vars > /dev/null << 'EOF' +# App-specific defaults for PiHole +var_unprivileged=1 +var_cpu=2 +var_ram=1024 +var_disk=10 +var_brg=vmbr0 +var_gateway=192.168.1.1 +var_hostname=pihole +var_container_storage=local +var_template_storage=local +EOF +``` + +--- + +### Method 3: Using Environment Variables + +Set defaults via environment before running: + +```bash +# Set as environment variables +export var_cpu=4 +export var_ram=2048 +export var_disk=20 +export var_hostname=my-container + +# Run installation +bash pihole-install.sh + +# These settings will be used +# (Can still be overridden by saved defaults) +``` + +--- + +## How to Use Saved Defaults + +### Using User Defaults + +```bash +# 1. Run any installation script +bash pihole-install.sh + +# 2. When asked for mode, select: +# Option: 3 (User Defaults) + +# 3. Your settings from default.vars are applied +# 4. Container created with your saved settings +``` + +### Using App Defaults + +```bash +# 1. Run the app you configured before +bash pihole-install.sh + +# 2. When asked for mode, select: +# Option: 4 (App Defaults) + +# 3. Your settings from defaults/pihole.vars are applied +# 4. Container created with exact same settings +``` + +### Overriding Saved Defaults + +```bash +# Even if you have defaults saved, +# you can override them with environment variables + +export var_cpu=8 # Override saved defaults +export var_hostname=custom-name + +bash pihole-install.sh +# Installation will use these values instead of saved defaults +``` + +--- + +## Managing Your Defaults + +### View Your Settings + +#### View User Defaults +```bash +cat /usr/local/community-scripts/default.vars +``` + +#### View App Defaults +```bash +cat /usr/local/community-scripts/defaults/pihole.vars +``` + +#### List All Saved App Defaults +```bash +ls -la /usr/local/community-scripts/defaults/ +``` + +### Edit Your Settings + +#### Edit User Defaults +```bash +sudo nano /usr/local/community-scripts/default.vars +``` + +#### Edit App Defaults +```bash +sudo nano /usr/local/community-scripts/defaults/pihole.vars +``` + +### Update Existing Defaults + +```bash +# Run installation again with your app +bash pihole-install.sh + +# Select: Advanced Settings +# Make desired changes +# At end, when asked to save: +# "Defaults already exist, Update?" +# Select: Yes + +# Your saved defaults are updated +``` + +### Delete Defaults + +#### Delete User Defaults +```bash +sudo rm /usr/local/community-scripts/default.vars +``` + +#### Delete App Defaults +```bash +sudo rm /usr/local/community-scripts/defaults/pihole.vars +``` + +#### Delete All App Defaults +```bash +sudo rm /usr/local/community-scripts/defaults/* +``` + +--- + +## Advanced Configuration + +### Available Variables + +All configurable variables start with `var_`: + +#### Resource Allocation +```bash +var_cpu=4 # CPU cores +var_ram=2048 # RAM in MB +var_disk=20 # Disk in GB +var_unprivileged=1 # 0=privileged, 1=unprivileged +``` + +#### Network +```bash +var_brg=vmbr0 # Bridge interface +var_net=veth # Network driver +var_gateway=192.168.1.1 # Default gateway +var_mtu=1500 # MTU size +var_vlan=100 # VLAN ID +``` + +#### System +```bash +var_hostname=pihole # Container name +var_timezone=Europe/Berlin # Timezone +var_pw=SecurePass123 # Root password +var_tags=dns,pihole # Tags for organization +var_verbose=yes # Enable verbose output +``` + +#### Security & Access +```bash +var_ssh=yes # Enable SSH +var_ssh_authorized_key="ssh-rsa AA..." # SSH public key +var_protection=1 # Enable protection flag +``` + +#### Features +```bash +var_fuse=1 # FUSE filesystem support +var_tun=1 # TUN device support +var_nesting=1 # Nesting (Docker in LXC) +var_keyctl=1 # Keyctl syscall +var_mknod=1 # Device node creation +``` + +#### Storage +```bash +var_container_storage=local # Where to store container +var_template_storage=local # Where to store templates +``` + +### Example Configuration Files + +#### Gaming Server Defaults +```bash +# High performance for gaming containers +var_cpu=8 +var_ram=4096 +var_disk=50 +var_unprivileged=0 +var_fuse=1 +var_nesting=1 +var_tags=gaming +``` + +#### Development Server +```bash +# Development with Docker support +var_cpu=4 +var_ram=2048 +var_disk=30 +var_unprivileged=1 +var_nesting=1 +var_ssh=yes +var_tags=development +``` + +#### IoT/Monitoring +```bash +# Low-resource, always-on containers +var_cpu=2 +var_ram=512 +var_disk=10 +var_unprivileged=1 +var_nesting=0 +var_fuse=0 +var_tun=0 +var_tags=iot,monitoring +``` + +--- + +## Troubleshooting + +### "App Defaults not available" Message + +**Problem**: You want to use App Defaults, but option says they're not available + +**Solution**: +1. You haven't created App Defaults yet for this app +2. Run the app with "Advanced Settings" +3. When finished, save as App Defaults +4. Next time, App Defaults will be available + +--- + +### "Settings not being applied" + +**Problem**: You saved defaults, but they're not being used + +**Checklist**: +```bash +# 1. Verify files exist +ls -la /usr/local/community-scripts/default.vars +ls -la /usr/local/community-scripts/defaults/.vars + +# 2. Check file permissions (should be readable) +stat /usr/local/community-scripts/default.vars + +# 3. Verify correct mode selected +# (Make sure you selected "User Defaults" or "App Defaults") + +# 4. Check for environment variable override +env | grep var_ +# If you have var_* set in environment, +# those override your saved defaults +``` + +--- + +### "Cannot write to defaults location" + +**Problem**: Permission denied when saving defaults + +**Solution**: +```bash +# Create the defaults directory if missing +sudo mkdir -p /usr/local/community-scripts/defaults + +# Fix permissions +sudo chmod 755 /usr/local/community-scripts +sudo chmod 755 /usr/local/community-scripts/defaults + +# Make sure you're running as root +sudo bash pihole-install.sh +``` + +--- + +### "Defaults directory doesn't exist" + +**Problem**: Script can't find where to save defaults + +**Solution**: +```bash +# Create the directory +sudo mkdir -p /usr/local/community-scripts/defaults + +# Verify +ls -la /usr/local/community-scripts/ +``` + +--- + +### Settings seem random or wrong + +**Problem**: Container gets different settings than expected + +**Possible Causes & Solutions**: + +```bash +# 1. Check if environment variables are set +env | grep var_ +# If you see var_* entries, those override your defaults +# Clear them: unset var_cpu var_ram (etc) + +# 2. Verify correct defaults are in files +cat /usr/local/community-scripts/default.vars +cat /usr/local/community-scripts/defaults/pihole.vars + +# 3. Check which mode you actually selected +# (Script output shows which defaults were applied) + +# 4. Check Proxmox logs for errors +sudo journalctl -u pve-daemon -n 50 +``` + +--- + +### "Variable not recognized" + +**Problem**: You set a variable that doesn't work + +**Solution**: +Only certain variables are allowed (security whitelist): + +``` +Allowed variables (starting with var_): +βœ“ var_cpu, var_ram, var_disk, var_unprivileged +βœ“ var_brg, var_gateway, var_mtu, var_vlan, var_net +βœ“ var_hostname, var_pw, var_timezone +βœ“ var_ssh, var_ssh_authorized_key +βœ“ var_fuse, var_tun, var_nesting, var_keyctl +βœ“ var_container_storage, var_template_storage +βœ“ var_tags, var_verbose +βœ“ var_apt_cacher, var_apt_cacher_ip +βœ“ var_protection, var_mount_fs + +βœ— Other variables are NOT supported +``` + +--- + +## Best Practices + +### βœ… Do's + +βœ“ Use **App Defaults** when you want app-specific settings +βœ“ Use **User Defaults** for your global preferences +βœ“ Edit defaults files directly with `nano` (safe) +βœ“ Keep separate App Defaults for each app +βœ“ Back up your defaults regularly +βœ“ Use environment variables for temporary overrides + +### ❌ Don'ts + +βœ— Don't use `source` on defaults files (security risk) +βœ— Don't put sensitive passwords in defaults (use SSH keys) +βœ— Don't modify defaults while installation is running +βœ— Don't delete defaults.d while containers are being created +βœ— Don't use special characters without escaping + +--- + +## Quick Reference + +### Defaults Locations + +| Type | Location | Example | +|------|----------|---------| +| User Defaults | `/usr/local/community-scripts/default.vars` | Global settings | +| App Defaults | `/usr/local/community-scripts/defaults/.vars` | PiHole-specific | +| Backup Dir | `/usr/local/community-scripts/defaults/` | All app defaults | + +### File Format + +```bash +# Comments start with # +var_name=value + +# No spaces around = +βœ“ var_cpu=4 +βœ— var_cpu = 4 + +# String values don't need quotes +βœ“ var_hostname=mycontainer +βœ“ var_hostname='mycontainer' + +# Values with spaces need quotes +βœ“ var_tags="docker,production,testing" +βœ— var_tags=docker,production,testing +``` + +### Command Reference + +```bash +# View defaults +cat /usr/local/community-scripts/default.vars + +# Edit defaults +sudo nano /usr/local/community-scripts/default.vars + +# List all app defaults +ls /usr/local/community-scripts/defaults/ + +# Backup your defaults +cp -r /usr/local/community-scripts/defaults/ ~/defaults-backup/ + +# Set temporary override +export var_cpu=8 +bash pihole-install.sh + +# Create custom defaults +sudo tee /usr/local/community-scripts/defaults/custom.vars << 'EOF' +var_cpu=4 +var_ram=2048 +EOF +``` + +--- + +## Getting Help + +### Need More Information? + +- πŸ“– [Main Documentation](../../docs/) +- πŸ› [Report Issues](https://github.com/community-scripts/ProxmoxVE/issues) +- πŸ’¬ [Discussions](https://github.com/community-scripts/ProxmoxVE/discussions) + +### Useful Commands + +```bash +# Check what variables are available +grep "var_" /path/to/app-install.sh | head -20 + +# Verify defaults syntax +cat /usr/local/community-scripts/default.vars + +# Monitor installation with defaults +bash pihole-install.sh 2>&1 | tee installation.log +``` + +--- + +## Document Information + +| Field | Value | +|-------|-------| +| Version | 1.0 | +| Last Updated | November 28, 2025 | +| Status | Current | +| License | MIT | + +--- + +**Happy configuring! πŸš€** diff --git a/docs/DEV_MODE.md b/docs/DEV_MODE.md new file mode 100644 index 000000000..5994068f1 --- /dev/null +++ b/docs/DEV_MODE.md @@ -0,0 +1,532 @@ +# Dev Mode - Debugging & Development Guide + +Development modes provide powerful debugging and testing capabilities for container creation and installation processes. + +## Quick Start + +```bash +# Single mode +export dev_mode="motd" +bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/wallabag.sh)" + +# Multiple modes (comma-separated) +export dev_mode="motd,keep,trace" +bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/wallabag.sh)" + +# Combine with verbose output +export var_verbose="yes" +export dev_mode="pause,logs" +bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/wallabag.sh)" +``` + +## Available Modes + +### 1. **motd** - Early SSH/MOTD Setup + +Sets up SSH access and MOTD **before** the main application installation. + +**Use Case**: + +- Quick access to container for manual debugging +- Continue installation manually if something goes wrong +- Verify container networking before main install + +**Behavior**: + +``` +βœ” Container created +βœ” Network configured +[DEV] Setting up MOTD and SSH before installation +βœ” [DEV] MOTD/SSH ready - container accessible +# Container is now accessible via SSH while installation proceeds +``` + +**Combined with**: `keep`, `breakpoint`, `logs` + +--- + +### 2. **keep** - Preserve Container on Failure + +Never delete the container when installation fails. Skips cleanup prompt. + +**Use Case**: + +- Repeated tests of the same installation +- Debugging failed installations +- Manual fix attempts + +**Behavior**: + +``` +βœ– Installation failed in container 107 (exit code: 1) +βœ” Container creation log: /tmp/create-lxc-107-abc12345.log +βœ” Installation log: /tmp/install-lxc-107-abc12345.log + +πŸ”§ [DEV] Keep mode active - container 107 preserved +root@proxmox:~# +``` + +**Container remains**: `pct enter 107` to access and debug + +**Combined with**: `motd`, `trace`, `logs` + +--- + +### 3. **trace** - Bash Command Tracing + +Enables `set -x` for complete command-line tracing. Shows every command before execution. + +**Use Case**: + +- Deep debugging of installation logic +- Understanding script flow +- Identifying where errors occur exactly + +**Behavior**: + +``` ++(/opt/wallabag/bin/console): /opt/wallabag/bin/console cache:warmup ++(/opt/wallabag/bin/console): env APP_ENV=prod /opt/wallabag/bin/console cache:warmup ++(/opt/wallabag/bin/console): [[ -d /opt/wallabag/app/cache ]] ++(/opt/wallabag/bin/console): rm -rf /opt/wallabag/app/cache/* +``` + +**⚠️ Warning**: Exposes passwords and secrets in log output! Only use in isolated environments. + +**Log Output**: All trace output saved to logs (see `logs` mode) + +**Combined with**: `keep`, `pause`, `logs` + +--- + +### 4. **pause** - Step-by-Step Execution + +Pauses after each major step (`msg_info`). Requires manual Enter press to continue. + +**Use Case**: + +- Inspect container state between steps +- Understand what each step does +- Identify which step causes problems + +**Behavior**: + +``` +⏳ Setting up Container OS +[PAUSE] Press Enter to continue... +⏳ Updating Container OS +[PAUSE] Press Enter to continue... +⏳ Installing Dependencies +[PAUSE] Press Enter to continue... +``` + +**Between pauses**: You can open another terminal and inspect the container + +```bash +# In another terminal while paused +pct enter 107 +root@container:~# df -h # Check disk usage +root@container:~# ps aux # Check running processes +``` + +**Combined with**: `motd`, `keep`, `logs` + +--- + +### 5. **breakpoint** - Interactive Shell on Error + +Opens interactive shell inside the container when an error occurs instead of cleanup prompt. + +**Use Case**: + +- Live debugging in the actual container +- Manual command testing +- Inspect container state at point of failure + +**Behavior**: + +``` +βœ– Installation failed in container 107 (exit code: 1) +βœ” Container creation log: /tmp/create-lxc-107-abc12345.log +βœ” Installation log: /tmp/install-lxc-107-abc12345.log + +πŸ› [DEV] Breakpoint mode - opening shell in container 107 +Type 'exit' to return to host +root@wallabag:~# + +# Now you can debug: +root@wallabag:~# tail -f /root/.install-abc12345.log +root@wallabag:~# mysql -u root -p$PASSWORD wallabag +root@wallabag:~# apt-get install -y strace +root@wallabag:~# exit + +Container 107 still running. Remove now? (y/N): n +πŸ”§ Container 107 kept for debugging +``` + +**Combined with**: `keep`, `logs`, `trace` + +--- + +### 6. **logs** - Persistent Logging + +Saves all logs to `/var/log/community-scripts/` with timestamps. Logs persist even on successful installation. + +**Use Case**: + +- Post-mortem analysis +- Performance analysis +- Automated testing with log collection +- CI/CD integration + +**Behavior**: + +``` +Logs location: /var/log/community-scripts/ + +create-lxc-abc12345-20251117_143022.log (host-side creation) +install-abc12345-20251117_143022.log (container-side installation) +``` + +**Access logs**: + +```bash +# View creation log +tail -f /var/log/community-scripts/create-lxc-*.log + +# Search for errors +grep ERROR /var/log/community-scripts/*.log + +# Analyze performance +grep "msg_info\|msg_ok" /var/log/community-scripts/create-*.log +``` + +**With trace mode**: Creates detailed trace of all commands + +```bash +grep "^+" /var/log/community-scripts/install-*.log +``` + +**Combined with**: All other modes (recommended for CI/CD) + +--- + +### 7. **dryrun** - Simulation Mode + +Shows all commands that would be executed without actually running them. + +**Use Case**: + +- Test script logic without making changes +- Verify command syntax +- Understand what will happen +- Pre-flight checks + +**Behavior**: + +``` +[DRYRUN] apt-get update +[DRYRUN] apt-get install -y curl +[DRYRUN] mkdir -p /opt/wallabag +[DRYRUN] cd /opt/wallabag +[DRYRUN] git clone https://github.com/wallabag/wallabag.git . +``` + +**No actual changes made**: Container/system remains unchanged + +**Combined with**: `trace` (shows dryrun trace), `logs` (shows what would run) + +--- + +## Mode Combinations + +### Development Workflow + +```bash +# First test: See what would happen +export dev_mode="dryrun,logs" +bash -c "$(curl ...)" + +# Then test with tracing and pauses +export dev_mode="pause,trace,logs" +bash -c "$(curl ...)" + +# Finally full debug with early SSH access +export dev_mode="motd,keep,breakpoint,logs" +bash -c "$(curl ...)" +``` + +### CI/CD Integration + +```bash +# Automated testing with full logging +export dev_mode="logs" +export var_verbose="yes" +bash -c "$(curl ...)" + +# Capture logs for analysis +tar czf installation-logs-$(date +%s).tar.gz /var/log/community-scripts/ +``` + +### Production-like Testing + +```bash +# Keep containers for manual verification +export dev_mode="keep,logs" +for i in {1..5}; do + bash -c "$(curl ...)" +done + +# Inspect all created containers +pct list +pct enter 100 +``` + +### Live Debugging + +```bash +# SSH in early, step through installation, debug on error +export dev_mode="motd,pause,breakpoint,keep" +bash -c "$(curl ...)" +``` + +--- + +## Environment Variables Reference + +### Dev Mode Variables + +- `dev_mode` (string): Comma-separated list of modes + - Format: `"motd,keep,trace"` + - Default: Empty (no dev modes) + +### Output Control + +- `var_verbose="yes"`: Show all command output (disables silent mode) + - Pairs well with: `trace`, `pause`, `logs` + +### Examples with vars + +```bash +# Maximum verbosity and debugging +export var_verbose="yes" +export dev_mode="motd,trace,pause,logs" +bash -c "$(curl ...)" + +# Silent debug (logs only) +export dev_mode="keep,logs" +bash -c "$(curl ...)" + +# Interactive debugging +export var_verbose="yes" +export dev_mode="motd,breakpoint" +bash -c "$(curl ...)" +``` + +--- + +## Troubleshooting with Dev Mode + +### "Installation failed at step X" + +```bash +export dev_mode="pause,logs" +# Step through until the failure point +# Check container state between pauses +pct enter 107 +``` + +### "Password/credentials not working" + +```bash +export dev_mode="motd,keep,trace" +# With trace mode, see exact password handling (be careful with logs!) +# Use motd to SSH in and test manually +ssh root@container-ip +``` + +### "Permission denied errors" + +```bash +export dev_mode="breakpoint,keep" +# Get shell at failure point +# Check file permissions, user context, SELinux status +ls -la /path/to/file +whoami +``` + +### "Networking issues" + +```bash +export dev_mode="motd" +# SSH in with motd mode before main install +ssh root@container-ip +ping 8.8.8.8 +nslookup example.com +``` + +### "Need to manually complete installation" + +```bash +export dev_mode="motd,keep" +# Container accessible via SSH while installation runs +# After failure, SSH in and manually continue +ssh root@container-ip +# ... manual commands ... +exit +# Then use 'keep' mode to preserve container for inspection +``` + +--- + +## Log Files Locations + +### Default (without `logs` mode) + +- Host creation: `/tmp/create-lxc-.log` +- Container install: Copied to `/tmp/install-lxc--.log` on failure + +### With `logs` mode + +- Host creation: `/var/log/community-scripts/create-lxc--.log` +- Container install: `/var/log/community-scripts/install--.log` + +### View logs + +```bash +# Tail in real-time +tail -f /var/log/community-scripts/*.log + +# Search for errors +grep -r "exit code [1-9]" /var/log/community-scripts/ + +# Filter by session +grep "ed563b19" /var/log/community-scripts/*.log +``` + +--- + +## Best Practices + +### βœ… DO + +- Use `logs` mode for CI/CD and automated testing +- Use `motd` for early SSH access during long installations +- Use `pause` when learning the installation flow +- Use `trace` when debugging logic issues (watch for secrets!) +- Combine modes for comprehensive debugging +- Archive logs after successful tests + +### ❌ DON'T + +- Use `trace` in production or with untrusted networks (exposes secrets) +- Leave `keep` mode enabled for unattended scripts (containers accumulate) +- Use `dryrun` and expect actual changes +- Commit `dev_mode` exports to production deployment scripts +- Use `breakpoint` in non-interactive environments (will hang) + +--- + +## Examples + +### Example 1: Debug a Failed Installation + +```bash +# Initial test to see the failure +export dev_mode="keep,logs" +bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/wallabag.sh)" + +# Container 107 kept, check logs +tail /var/log/community-scripts/install-*.log + +# SSH in to debug +pct enter 107 +root@wallabag:~# cat /root/.install-*.log | tail -100 +root@wallabag:~# apt-get update # Retry the failing command +root@wallabag:~# exit + +# Re-run with manual step-through +export dev_mode="motd,pause,keep" +bash -c "$(curl ...)" +``` + +### Example 2: Verify Installation Steps + +```bash +export dev_mode="pause,logs" +export var_verbose="yes" +bash -c "$(curl ...)" + +# Press Enter through each step +# Monitor container in another terminal +# pct enter 107 +# Review logs in real-time +``` + +### Example 3: CI/CD Pipeline Integration + +```bash +#!/bin/bash +export dev_mode="logs" +export var_verbose="no" + +for app in wallabag nextcloud wordpress; do + echo "Testing $app installation..." + APP="$app" bash -c "$(curl ...)" || { + echo "FAILED: $app" + tar czf logs-$app.tar.gz /var/log/community-scripts/ + exit 1 + } + echo "SUCCESS: $app" +done + +echo "All installations successful" +tar czf all-logs.tar.gz /var/log/community-scripts/ +``` + +--- + +## Advanced Usage + +### Custom Log Analysis + +```bash +# Extract all errors +grep "ERROR\|exit code [1-9]" /var/log/community-scripts/*.log + +# Performance timeline +grep "^$(date +%Y-%m-%d)" /var/log/community-scripts/*.log | grep "msg_" + +# Memory usage during install +grep "free\|available" /var/log/community-scripts/*.log +``` + +### Integration with External Tools + +```bash +# Send logs to Elasticsearch +curl -X POST "localhost:9200/installation-logs/_doc" \ + -H 'Content-Type: application/json' \ + -d @/var/log/community-scripts/install-*.log + +# Archive for compliance +tar czf installation-records-$(date +%Y%m).tar.gz \ + /var/log/community-scripts/ +gpg --encrypt installation-records-*.tar.gz +``` + +--- + +## Support & Issues + +When reporting installation issues, always include: + +```bash +# Collect all relevant information +export dev_mode="logs" +# Run the failing installation +# Then provide: +tar czf debug-logs.tar.gz /var/log/community-scripts/ +``` + +Include the `debug-logs.tar.gz` when reporting issues for better diagnostics. diff --git a/docs/EXIT_CODES.md b/docs/EXIT_CODES.md new file mode 100644 index 000000000..091f92664 --- /dev/null +++ b/docs/EXIT_CODES.md @@ -0,0 +1,298 @@ +# Exit Code Reference + +Comprehensive documentation of all exit codes used in ProxmoxVE scripts. + +## Table of Contents + +- [Generic/Shell Errors (1-255)](#genericshell-errors) +- [Package Manager Errors (100-101, 255)](#package-manager-errors) +- [Node.js/npm Errors (243-254)](#nodejsnpm-errors) +- [Python/pip Errors (210-212)](#pythonpip-errors) +- [Database Errors (231-254)](#database-errors) +- [Proxmox Custom Codes (200-231)](#proxmox-custom-codes) + +--- + +## Generic/Shell Errors + +Standard Unix/Linux exit codes used across all scripts. + +| Code | Description | Common Causes | Solutions | +| ------- | --------------------------------------- | ----------------------------------------- | ---------------------------------------------- | +| **1** | General error / Operation not permitted | Permission denied, general failure | Check user permissions, run as root if needed | +| **2** | Misuse of shell builtins | Syntax error in script | Review script syntax, check bash version | +| **126** | Command cannot execute | Permission problem, not executable | `chmod +x script.sh` or check file permissions | +| **127** | Command not found | Missing binary, wrong PATH | Install required package, check PATH variable | +| **128** | Invalid argument to exit | Invalid exit code passed | Use exit codes 0-255 only | +| **130** | Terminated by Ctrl+C (SIGINT) | User interrupted script | Expected behavior, no action needed | +| **137** | Killed (SIGKILL) | Out of memory, forced termination | Check memory usage, increase RAM allocation | +| **139** | Segmentation fault | Memory access violation, corrupted binary | Reinstall package, check system stability | +| **143** | Terminated (SIGTERM) | Graceful shutdown signal | Expected during container stops | + +--- + +## Package Manager Errors + +APT, DPKG, and package installation errors. + +| Code | Description | Common Causes | Solutions | +| ------- | -------------------------- | --------------------------------------- | ------------------------------------------------- | +| **100** | APT: Package manager error | Broken packages, dependency conflicts | `apt --fix-broken install`, `dpkg --configure -a` | +| **101** | APT: Configuration error | Malformed sources.list, bad repo config | Check `/etc/apt/sources.list`, run `apt update` | +| **255** | DPKG: Fatal internal error | Corrupted package database | `dpkg --configure -a`, restore from backup | + +--- + +## Node.js/npm Errors + +Node.js runtime and package manager errors. + +| Code | Description | Common Causes | Solutions | +| ------- | ------------------------------------------ | ------------------------------ | ---------------------------------------------- | +| **243** | Node.js: Out of memory | JavaScript heap exhausted | Increase `--max-old-space-size`, optimize code | +| **245** | Node.js: Invalid command-line option | Wrong Node.js flags | Check Node.js version, verify CLI options | +| **246** | Node.js: Internal JavaScript Parse Error | Syntax error in JS code | Review JavaScript syntax, check dependencies | +| **247** | Node.js: Fatal internal error | Node.js runtime crash | Update Node.js, check for known bugs | +| **248** | Node.js: Invalid C++ addon / N-API failure | Native module incompatibility | Rebuild native modules, update packages | +| **249** | Node.js: Inspector error | Debug/inspect protocol failure | Disable inspector, check port conflicts | +| **254** | npm/pnpm/yarn: Unknown fatal error | Package manager crash | Clear cache, reinstall package manager | + +--- + +## Python/pip Errors + +Python runtime and package installation errors. + +| Code | Description | Common Causes | Solutions | +| ------- | ------------------------------------ | --------------------------------------- | -------------------------------------------------------- | +| **210** | Python: Virtualenv missing or broken | venv not created, corrupted environment | `python3 -m venv venv`, recreate virtualenv | +| **211** | Python: Dependency resolution failed | Conflicting package versions | Use `pip install --upgrade`, check requirements.txt | +| **212** | Python: Installation aborted | EXTERNALLY-MANAGED, permission denied | Use `--break-system-packages` or venv, check permissions | + +--- + +## Database Errors + +### PostgreSQL (231-234) + +| Code | Description | Common Causes | Solutions | +| ------- | ----------------------- | ---------------------------------- | ----------------------------------------------------- | +| **231** | Connection failed | Server not running, wrong socket | `systemctl start postgresql`, check connection string | +| **232** | Authentication failed | Wrong credentials | Verify username/password, check `pg_hba.conf` | +| **233** | Database does not exist | Database not created | `CREATE DATABASE`, restore from backup | +| **234** | Fatal error in query | Syntax error, constraint violation | Review SQL syntax, check constraints | + +### MySQL/MariaDB (241-244) + +| Code | Description | Common Causes | Solutions | +| ------- | ----------------------- | ---------------------------------- | ---------------------------------------------------- | +| **241** | Connection failed | Server not running, wrong socket | `systemctl start mysql`, check connection parameters | +| **242** | Authentication failed | Wrong credentials | Verify username/password, grant privileges | +| **243** | Database does not exist | Database not created | `CREATE DATABASE`, restore from backup | +| **244** | Fatal error in query | Syntax error, constraint violation | Review SQL syntax, check constraints | + +### MongoDB (251-254) + +| Code | Description | Common Causes | Solutions | +| ------- | --------------------- | -------------------- | ------------------------------------------ | +| **251** | Connection failed | Server not running | `systemctl start mongod`, check port 27017 | +| **252** | Authentication failed | Wrong credentials | Verify username/password, create user | +| **253** | Database not found | Database not created | Database auto-created on first write | +| **254** | Fatal query error | Invalid query syntax | Review MongoDB query syntax | + +--- + +## Proxmox Custom Codes + +Custom exit codes specific to ProxmoxVE scripts. + +### Container Creation Errors (200-209) + +| Code | Description | Common Causes | Solutions | +| ------- | ---------------------------------------------- | ------------------------------------------------------- | ------------------------------------------------------- | +| **200** | Failed to create lock file | Permission denied, disk full | Check `/tmp` permissions, free disk space | +| **203** | Missing CTID variable | Script configuration error | Set CTID in script or via prompt | +| **204** | Missing PCT_OSTYPE variable | Template selection failed | Verify template availability | +| **205** | Invalid CTID (<100) | CTID below minimum value | Use CTID β‰₯ 100 (1-99 reserved for Proxmox) | +| **206** | CTID already in use | Container/VM with same ID exists | Check `pct list` and `/etc/pve/lxc/`, use different ID | +| **207** | Password contains unescaped special characters | Special chars like `-`, `/`, `\`, `*` at start/end | Avoid leading special chars, use alphanumeric passwords | +| **208** | Invalid configuration | DNS format (`.home` vs `home`), MAC format (`-` vs `:`) | Remove leading dots from DNS, use `:` in MAC addresses | +| **209** | Container creation failed | Multiple possible causes | Check logs in `/tmp/pct_create_*.log`, verify template | + +### Cluster & Storage Errors (210, 214, 217) + +| Code | Description | Common Causes | Solutions | +| ------- | --------------------------------- | ---------------------------------- | ----------------------------------------------------------- | +| **210** | Cluster not quorate | Cluster nodes down, network issues | Check cluster status: `pvecm status`, fix node connectivity | +| **211** | Timeout waiting for template lock | Concurrent download in progress | Wait for other download to complete (60s timeout) | +| **214** | Not enough storage space | Disk full, quota exceeded | Free disk space, increase storage allocation | +| **217** | Storage does not support rootdir | Wrong storage type selected | Use storage supporting containers (dir, zfspool, lvm-thin) | + +### Container Verification Errors (215-216) + +| Code | Description | Common Causes | Solutions | +| ------- | -------------------------------- | -------------------------------- | --------------------------------------------------------- | +| **215** | Container created but not listed | Ghost state, incomplete creation | Check `/etc/pve/lxc/CTID.conf`, remove manually if needed | +| **216** | RootFS entry missing in config | Incomplete container creation | Delete container, retry creation | + +### Template Errors (218, 220-223, 225) + +| Code | Description | Common Causes | Solutions | +| ------- | ----------------------------------------- | ------------------------------------------------ | ----------------------------------------------------------- | +| **218** | Template file corrupted or incomplete | Download interrupted, file <1MB, invalid archive | Delete template, run `pveam update && pveam download` | +| **220** | Unable to resolve template path | Template storage not accessible | Check storage availability, verify permissions | +| **221** | Template file exists but not readable | Permission denied | `chmod 644 template.tar.zst`, check storage permissions | +| **222** | Template download failed after 3 attempts | Network issues, storage problems | Check internet connectivity, verify storage space | +| **223** | Template not available after download | Storage sync issue, I/O delay | Wait a few seconds, verify storage is mounted | +| **225** | No template available for OS/Version | Unsupported OS version, catalog outdated | Run `pveam update`, check `pveam available -section system` | + +### LXC Stack Errors (231) + +| Code | Description | Common Causes | Solutions | +| ------- | ------------------------------ | ------------------------------------------- | -------------------------------------------- | +| **231** | LXC stack upgrade/retry failed | Outdated `pve-container`, Debian 13.1 issue | See [Debian 13.1 Fix Guide](#debian-131-fix) | + +--- + +## Special Case: Debian 13.1 "unsupported version" Error + +### Problem + +``` +TASK ERROR: unable to create CT 129 - unsupported debian version '13.1' +``` + +### Root Cause + +Outdated `pve-container` package doesn't recognize Debian 13 (Trixie). + +### Solutions + +#### Option 1: Full System Upgrade (Recommended) + +```bash +apt update +apt full-upgrade -y +reboot +``` + +Verify fix: + +```bash +dpkg -l pve-container +# PVE 8: Should show 5.3.3+ +# PVE 9: Should show 6.0.13+ +``` + +#### Option 2: Update Only pve-container + +```bash +apt update +apt install --only-upgrade pve-container -y +``` + +**Warning:** If Proxmox fails to boot after this, your system was inconsistent. Perform Option 1 instead. + +#### Option 3: Verify Repository Configuration + +Many users disable Enterprise repos but forget to add no-subscription repos. + +**For PVE 9 (Trixie):** + +```bash +cat /etc/apt/sources.list.d/pve-no-subscription.list +``` + +Should contain: + +``` +deb http://download.proxmox.com/debian/pve trixie pve-no-subscription +deb http://download.proxmox.com/debian/ceph-squid trixie no-subscription +``` + +**For PVE 8 (Bookworm):** + +``` +deb http://download.proxmox.com/debian/pve bookworm pve-no-subscription +deb http://download.proxmox.com/debian/ceph-quincy bookworm no-subscription +``` + +Then: + +```bash +apt update +apt full-upgrade -y +``` + +### Reference + +Official discussion: [GitHub #8126](https://github.com/community-scripts/ProxmoxVE/discussions/8126) + +--- + +## Troubleshooting Tips + +### Finding Error Details + +1. **Check logs:** + + ```bash + tail -n 50 /tmp/pct_create_*.log + ``` + +2. **Enable verbose mode:** + + ```bash + bash -x script.sh # Shows every command executed + ``` + +3. **Check container status:** + + ```bash + pct list + pct status CTID + ``` + +4. **Verify storage:** + ```bash + pvesm status + df -h + ``` + +### Common Patterns + +- **Exit 0 with error message:** Configuration validation failed (check DNS, MAC, password format) +- **Exit 206 but container not visible:** Ghost container state - check `/etc/pve/lxc/` manually +- **Exit 209 generic error:** Check `/tmp/pct_create_*.log` for specific `pct create` failure reason +- **Exit 218 or 222:** Template issues - delete and re-download template + +--- + +## Quick Reference Chart + +| Exit Code Range | Category | Typical Issue | +| --------------- | ------------------ | ------------------------------------------- | +| 1-2, 126-143 | Shell/System | Permissions, signals, missing commands | +| 100-101, 255 | Package Manager | APT/DPKG errors, broken packages | +| 200-209 | Container Creation | CTID, password, configuration | +| 210-217 | Storage/Cluster | Disk space, quorum, storage type | +| 218-225 | Templates | Download, corruption, availability | +| 231-254 | Databases/Runtime | PostgreSQL, MySQL, MongoDB, Node.js, Python | + +--- + +## Contributing + +Found an undocumented exit code or have a solution to share? Please: + +1. Open an issue on [GitHub](https://github.com/community-scripts/ProxmoxVE/issues) +2. Include: + - Exit code number + - Error message + - Steps to reproduce + - Solution that worked for you + +--- + +_Last updated: November 2025_ +_ProxmoxVE Version: 2.x_ diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 000000000..67e93c66b --- /dev/null +++ b/docs/README.md @@ -0,0 +1,290 @@ +# πŸ“š ProxmoxVE Documentation + +Complete guide to all ProxmoxVE documentation - quickly find what you need. + +--- + +## 🎯 **Quick Navigation by Goal** + +### πŸ‘€ **I want to...** + +**Contribute a new application** +β†’ Start with: [contribution/README.md](contribution/README.md) +β†’ Then: [ct/DETAILED_GUIDE.md](ct/DETAILED_GUIDE.md) + [install/DETAILED_GUIDE.md](install/DETAILED_GUIDE.md) + +**Understand the architecture** +β†’ Read: [TECHNICAL_REFERENCE.md](TECHNICAL_REFERENCE.md) +β†’ Then: [misc/README.md](misc/README.md) + +**Debug a failed installation** +β†’ Check: [EXIT_CODES.md](EXIT_CODES.md) +β†’ Then: [DEV_MODE.md](DEV_MODE.md) +β†’ See also: [misc/error_handler.func/](misc/error_handler.func/) + +**Configure system defaults** +β†’ Read: [DEFAULTS_SYSTEM_GUIDE.md](DEFAULTS_SYSTEM_GUIDE.md) + +**Develop a function library** +β†’ Study: [misc/](misc/) documentation + +--- + +## πŸ‘€ **Quick Start by Role** + +### **I'm a...** + +**New Contributor** +β†’ Start: [contribution/README.md](contribution/README.md) +β†’ Then: Choose your path below + +**Container Creator** +β†’ Read: [ct/README.md](ct/README.md) +β†’ Deep Dive: [ct/DETAILED_GUIDE.md](ct/DETAILED_GUIDE.md) +β†’ Reference: [misc/build.func/](misc/build.func/) + +**Installation Script Developer** +β†’ Read: [install/README.md](install/README.md) +β†’ Deep Dive: [install/DETAILED_GUIDE.md](install/DETAILED_GUIDE.md) +β†’ Reference: [misc/tools.func/](misc/tools.func/) + +**VM Provisioner** +β†’ Read: [vm/README.md](vm/README.md) +β†’ Reference: [misc/cloud-init.func/](misc/cloud-init.func/) + +**Tools Developer** +β†’ Read: [tools/README.md](tools/README.md) +β†’ Reference: [misc/build.func/](misc/build.func/) + +**API Integrator** +β†’ Read: [api/README.md](api/README.md) +β†’ Reference: [misc/api.func/](misc/api.func/) + +**System Operator** +β†’ Start: [EXIT_CODES.md](EXIT_CODES.md) +β†’ Then: [DEFAULTS_SYSTEM_GUIDE.md](DEFAULTS_SYSTEM_GUIDE.md) +β†’ Debug: [DEV_MODE.md](DEV_MODE.md) + +**Architect** +β†’ Read: [TECHNICAL_REFERENCE.md](TECHNICAL_REFERENCE.md) +β†’ Deep Dive: [misc/README.md](misc/README.md) + +--- + +## πŸ“‚ **Documentation Structure** + +### Project-Mirrored Directories + +Each major project directory has documentation: + +``` +ProxmoxVE/ +β”œβ”€ ct/ ↔ docs/ct/ (README.md + DETAILED_GUIDE.md) +β”œβ”€ install/ ↔ docs/install/ (README.md + DETAILED_GUIDE.md) +β”œβ”€ vm/ ↔ docs/vm/ (README.md) +β”œβ”€ tools/ ↔ docs/tools/ (README.md) +β”œβ”€ api/ ↔ docs/api/ (README.md) +└─ misc/ ↔ docs/misc/ (9 function libraries) +``` + +### Core Documentation + +| Document | Purpose | Audience | +|----------|---------|----------| +| [contribution/README.md](contribution/README.md) | How to contribute | Contributors | +| [ct/DETAILED_GUIDE.md](ct/DETAILED_GUIDE.md) | Create ct scripts | Container developers | +| [install/DETAILED_GUIDE.md](install/DETAILED_GUIDE.md) | Create install scripts | Installation developers | +| [TECHNICAL_REFERENCE.md](TECHNICAL_REFERENCE.md) | Architecture deep-dive | Architects, advanced users | +| [DEFAULTS_SYSTEM_GUIDE.md](DEFAULTS_SYSTEM_GUIDE.md) | Configuration system | Operators, power users | +| [EXIT_CODES.md](EXIT_CODES.md) | Exit code reference | Troubleshooters | +| [DEV_MODE.md](DEV_MODE.md) | Debugging tools | Developers | + +--- + +## πŸ“‚ **Directory Guide** + +### [ct/](ct/) - Container Scripts +Documentation for `/ct` - Container creation scripts that run on the Proxmox host. + +**Includes**: +- Overview of container creation process +- Deep dive: [DETAILED_GUIDE.md](ct/DETAILED_GUIDE.md) - Complete reference with examples +- Reference to [misc/build.func/](misc/build.func/) +- Quick start for creating new containers + +### [install/](install/) - Installation Scripts +Documentation for `/install` - Scripts that run inside containers to install applications. + +**Includes**: +- Overview of 10-phase installation pattern +- Deep dive: [DETAILED_GUIDE.md](install/DETAILED_GUIDE.md) - Complete reference with examples +- Reference to [misc/tools.func/](misc/tools.func/) +- Alpine vs Debian differences + +### [vm/](vm/) - Virtual Machine Scripts +Documentation for `/vm` - VM creation scripts using cloud-init provisioning. + +**Includes**: +- Overview of VM provisioning +- Link to [misc/cloud-init.func/](misc/cloud-init.func/) +- VM vs Container comparison +- Cloud-init examples + +### [tools/](tools/) - Tools & Utilities +Documentation for `/tools` - Management tools and add-ons. + +**Includes**: +- Overview of tools structure +- Integration points +- Contributing new tools +- Common operations + +### [api/](api/) - API Integration +Documentation for `/api` - Telemetry and API backend. + +**Includes**: +- API overview +- Integration methods +- API endpoints +- Privacy information + +### [misc/](misc/) - Function Libraries +Documentation for `/misc` - 9 core function libraries with complete references. + +**Contains**: +- **build.func/** - Container orchestration (7 files) +- **core.func/** - Utilities and messaging (5 files) +- **error_handler.func/** - Error handling (5 files) +- **api.func/** - API integration (5 files) +- **install.func/** - Container setup (5 files) +- **tools.func/** - Package installation (6 files) +- **alpine-install.func/** - Alpine setup (5 files) +- **alpine-tools.func/** - Alpine tools (5 files) +- **cloud-init.func/** - VM provisioning (5 files) + +--- + +## πŸŽ“ **Learning Paths** + +### Path 1: First-Time Contributor (2-3 hours) + +1. [contribution/README.md](contribution/README.md) - Quick Start +2. Pick your area: + - Containers β†’ [ct/README.md](ct/README.md) + [ct/DETAILED_GUIDE.md](ct/DETAILED_GUIDE.md) + - Installation β†’ [install/README.md](install/README.md) + [install/DETAILED_GUIDE.md](install/DETAILED_GUIDE.md) + - VMs β†’ [vm/README.md](vm/README.md) +3. Study existing similar script +4. Create your contribution +5. Submit PR + +### Path 2: Intermediate Developer (4-6 hours) + +1. [TECHNICAL_REFERENCE.md](TECHNICAL_REFERENCE.md) +2. Dive into function libraries: + - [misc/build.func/README.md](misc/build.func/README.md) + - [misc/tools.func/README.md](misc/tools.func/README.md) + - [misc/install.func/README.md](misc/install.func/README.md) +3. Study advanced examples +4. Create complex applications + +### Path 3: Advanced Architect (8+ hours) + +1. All of Intermediate Path +2. Study all 9 function libraries in depth +3. [DEFAULTS_SYSTEM_GUIDE.md](DEFAULTS_SYSTEM_GUIDE.md) - Configuration system +4. [DEV_MODE.md](DEV_MODE.md) - Debugging and development +5. Design new features or function libraries + +### Path 4: Troubleshooter (30 minutes - 1 hour) + +1. [EXIT_CODES.md](EXIT_CODES.md) - Find error code +2. [DEV_MODE.md](DEV_MODE.md) - Run with debugging +3. Check relevant function library docs +4. Review logs and fix + +--- + +## πŸ“Š **By the Numbers** + +| Metric | Count | +|--------|:---:| +| **Documentation Files** | 63 | +| **Total Lines** | 15,000+ | +| **Function Libraries** | 9 | +| **Functions Documented** | 150+ | +| **Code Examples** | 50+ | +| **Flowcharts** | 15+ | +| **Do/Don't Sections** | 20+ | +| **Real-World Examples** | 30+ | + +--- + +## πŸ” **Find It Fast** + +### By Feature +- **How do I create a container?** β†’ [ct/DETAILED_GUIDE.md](ct/DETAILED_GUIDE.md) +- **How do I create an install script?** β†’ [install/DETAILED_GUIDE.md](install/DETAILED_GUIDE.md) +- **How do I create a VM?** β†’ [vm/README.md](vm/README.md) +- **How do I install Node.js?** β†’ [misc/tools.func/](misc/tools.func/) +- **How do I debug?** β†’ [DEV_MODE.md](DEV_MODE.md) + +### By Error +- **Exit code 206?** β†’ [EXIT_CODES.md](EXIT_CODES.md) +- **Network failed?** β†’ [misc/install.func/](misc/install.func/) +- **Package error?** β†’ [misc/tools.func/](misc/tools.func/) + +### By Role +- **Contributor** β†’ [contribution/README.md](contribution/README.md) +- **Operator** β†’ [DEFAULTS_SYSTEM_GUIDE.md](DEFAULTS_SYSTEM_GUIDE.md) +- **Developer** β†’ [TECHNICAL_REFERENCE.md](TECHNICAL_REFERENCE.md) +- **Architect** β†’ [misc/README.md](misc/README.md) + +--- + +## βœ… **Documentation Features** + +- βœ… **Project-mirrored structure** - Organized like the actual project +- βœ… **Complete function references** - Every function documented +- βœ… **Real-world examples** - Copy-paste ready code +- βœ… **Visual flowcharts** - ASCII diagrams of workflows +- βœ… **Integration guides** - How components connect +- βœ… **Troubleshooting** - Common issues and solutions +- βœ… **Best practices** - DO/DON'T sections throughout +- βœ… **Learning paths** - Structured curriculum by role +- βœ… **Quick references** - Fast lookup by error code +- βœ… **Comprehensive navigation** - This page + +--- + +## πŸš€ **Start Here** + +**New to ProxmoxVE?** β†’ [contribution/README.md](contribution/README.md) + +**Looking for something specific?** β†’ Choose your role above or browse by directory + +**Need to debug?** β†’ [EXIT_CODES.md](EXIT_CODES.md) + +**Want to understand architecture?** β†’ [TECHNICAL_REFERENCE.md](TECHNICAL_REFERENCE.md) + +--- + +## 🀝 **Contributing Documentation** + +Found an error? Want to improve docs? + +1. See: [contribution/README.md](contribution/README.md) for full contribution guide +2. Open issue: [GitHub Issues](https://github.com/community-scripts/ProxmoxVE/issues) +3. Or submit PR with improvements + +--- + +## πŸ“ **Status** + +- **Last Updated**: December 2025 +- **Version**: 2.3 (Consolidated & Reorganized) +- **Completeness**: βœ… 100% - All components documented +- **Quality**: βœ… Production-ready +- **Structure**: βœ… Clean and organized + +--- + +**Welcome to ProxmoxVE! Start with [CONTRIBUTION_GUIDE.md](CONTRIBUTION_GUIDE.md) or choose your role above.** πŸš€ diff --git a/docs/TECHNICAL_REFERENCE.md b/docs/TECHNICAL_REFERENCE.md new file mode 100644 index 000000000..aea5148c9 --- /dev/null +++ b/docs/TECHNICAL_REFERENCE.md @@ -0,0 +1,881 @@ +# Technical Reference: Configuration System Architecture + +> **For Developers and Advanced Users** +> +> *Deep dive into how the defaults and configuration system works* + +--- + +## Table of Contents + +1. [System Architecture](#system-architecture) +2. [File Format Specifications](#file-format-specifications) +3. [Function Reference](#function-reference) +4. [Variable Precedence](#variable-precedence) +5. [Data Flow Diagrams](#data-flow-diagrams) +6. [Security Model](#security-model) +7. [Implementation Details](#implementation-details) + +--- + +## System Architecture + +### Component Overview + +``` +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ Installation Script β”‚ +β”‚ (pihole-install.sh, docker-install.sh, etc.) β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + v +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ build.func Library β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ variables() β”‚ β”‚ +β”‚ β”‚ - Initialize NSAPP, var_install, etc. β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ install_script() β”‚ β”‚ +β”‚ β”‚ - Display mode menu β”‚ β”‚ +β”‚ β”‚ - Route to appropriate workflow β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ base_settings() β”‚ β”‚ +β”‚ β”‚ - Apply built-in defaults β”‚ β”‚ +β”‚ β”‚ - Read environment variables (var_*) β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ load_vars_file() β”‚ β”‚ +β”‚ β”‚ - Safe file parsing (NO source/eval) β”‚ β”‚ +β”‚ β”‚ - Whitelist validation β”‚ β”‚ +β”‚ β”‚ - Value sanitization β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ default_var_settings() β”‚ β”‚ +β”‚ β”‚ - Load user defaults β”‚ β”‚ +β”‚ β”‚ - Display summary β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ maybe_offer_save_app_defaults() β”‚ β”‚ +β”‚ β”‚ - Offer to save current settings β”‚ β”‚ +β”‚ β”‚ - Handle updates vs. new saves β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + v +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ Configuration Files (on Disk) β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ /usr/local/community-scripts/default.vars β”‚ β”‚ +β”‚ β”‚ (User global defaults) β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ /usr/local/community-scripts/defaults/*.vars β”‚ β”‚ +β”‚ β”‚ (App-specific defaults) β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +``` + +--- + +## File Format Specifications + +### User Defaults: `default.vars` + +**Location**: `/usr/local/community-scripts/default.vars` + +**MIME Type**: `text/plain` + +**Encoding**: UTF-8 (no BOM) + +**Format Specification**: + +``` +# File Format: Simple key=value pairs +# Purpose: Store global user defaults +# Security: Sanitized values, whitelist validation + +# Comments and blank lines are ignored +# Line format: var_name=value +# No spaces around the equals sign +# String values do not need quoting (but may be quoted) + +[CONTENT] +var_cpu=4 +var_ram=2048 +var_disk=20 +var_hostname=mydefault +var_brg=vmbr0 +var_gateway=192.168.1.1 +``` + +**Formal Grammar**: + +``` +FILE := (BLANK_LINE | COMMENT_LINE | VAR_LINE)* +BLANK_LINE := \n +COMMENT_LINE := '#' [^\n]* \n +VAR_LINE := VAR_NAME '=' VAR_VALUE \n +VAR_NAME := 'var_' [a-z_]+ +VAR_VALUE := [^\n]* # Any printable characters except newline +``` + +**Constraints**: + +| Constraint | Value | +|-----------|-------| +| Max file size | 64 KB | +| Max line length | 1024 bytes | +| Max variables | 100 | +| Allowed var names | `var_[a-z_]+` | +| Value validation | Whitelist + Sanitization | + +**Example Valid File**: + +```bash +# Global User Defaults +# Created: 2024-11-28 + +# Resource defaults +var_cpu=4 +var_ram=2048 +var_disk=20 + +# Network defaults +var_brg=vmbr0 +var_gateway=192.168.1.1 +var_mtu=1500 +var_vlan=100 + +# System defaults +var_timezone=Europe/Berlin +var_hostname=default-container + +# Storage +var_container_storage=local +var_template_storage=local + +# Security +var_ssh=yes +var_protection=0 +var_unprivileged=1 +``` + +### App Defaults: `.vars` + +**Location**: `/usr/local/community-scripts/defaults/.vars` + +**Format**: Identical to `default.vars` + +**Naming Convention**: `.vars` + +- `nsapp` = lowercase app name with spaces removed +- Examples: + - `pihole` β†’ `pihole.vars` + - `opnsense` β†’ `opnsense.vars` + - `docker compose` β†’ `dockercompose.vars` + +**Example App Defaults**: + +```bash +# App-specific defaults for PiHole (pihole) +# Generated on 2024-11-28T15:32:00Z +# These override user defaults when installing pihole + +var_unprivileged=1 +var_cpu=2 +var_ram=1024 +var_disk=10 +var_brg=vmbr0 +var_net=veth +var_gateway=192.168.1.1 +var_hostname=pihole +var_timezone=Europe/Berlin +var_container_storage=local +var_template_storage=local +var_tags=dns,pihole +``` + +--- + +## Function Reference + +### `load_vars_file()` + +**Purpose**: Safely load variables from .vars files without using `source` or `eval` + +**Signature**: +```bash +load_vars_file(filepath) +``` + +**Parameters**: + +| Param | Type | Required | Example | +|-------|------|----------|---------| +| filepath | String | Yes | `/usr/local/community-scripts/default.vars` | + +**Returns**: +- `0` on success +- `1` on error (file missing, parse error, etc.) + +**Environment Side Effects**: +- Sets all parsed `var_*` variables as shell variables +- Does NOT unset variables if file missing (safe) +- Does NOT affect other variables + +**Implementation Pattern**: + +```bash +load_vars_file() { + local file="$1" + + # File must exist + [ -f "$file" ] || return 0 + + # Parse line by line (not with source/eval) + local line key val + while IFS='=' read -r key val || [ -n "$key" ]; do + # Skip comments and empty lines + [[ "$key" =~ ^[[:space:]]*# ]] && continue + [[ -z "$key" ]] && continue + + # Validate key is in whitelist + _is_whitelisted_key "$key" || continue + + # Sanitize and export value + val="$(_sanitize_value "$val")" + [ $? -eq 0 ] && export "$key=$val" + done < "$file" + + return 0 +} +``` + +**Usage Examples**: + +```bash +# Load user defaults +load_vars_file "/usr/local/community-scripts/default.vars" + +# Load app-specific defaults +load_vars_file "$(get_app_defaults_path)" + +# Check if successful +if load_vars_file "$vars_path"; then + echo "Settings loaded successfully" +else + echo "Failed to load settings" +fi + +# Values are now available as variables +echo "Using $var_cpu cores" +echo "Allocating ${var_ram} MB RAM" +``` + +--- + +### `get_app_defaults_path()` + +**Purpose**: Get the full path for app-specific defaults file + +**Signature**: +```bash +get_app_defaults_path() +``` + +**Parameters**: None + +**Returns**: +- String: Full path to app defaults file + +**Implementation**: + +```bash +get_app_defaults_path() { + local n="${NSAPP:-${APP,,}}" + echo "/usr/local/community-scripts/defaults/${n}.vars" +} +``` + +**Usage Examples**: + +```bash +# Get app defaults path +app_defaults="$(get_app_defaults_path)" +echo "App defaults at: $app_defaults" + +# Check if app defaults exist +if [ -f "$(get_app_defaults_path)" ]; then + echo "App defaults available" +fi + +# Load app defaults +load_vars_file "$(get_app_defaults_path)" +``` + +--- + +### `default_var_settings()` + +**Purpose**: Load and display user global defaults + +**Signature**: +```bash +default_var_settings() +``` + +**Parameters**: None + +**Returns**: +- `0` on success +- `1` on error + +**Workflow**: + +``` +1. Find default.vars location + (usually /usr/local/community-scripts/default.vars) + +2. Create if missing + +3. Load variables from file + +4. Map var_verbose β†’ VERBOSE variable + +5. Call base_settings (apply to container config) + +6. Call echo_default (display summary) +``` + +**Implementation Pattern**: + +```bash +default_var_settings() { + local VAR_WHITELIST=( + var_apt_cacher var_apt_cacher_ip var_brg var_cpu var_disk var_fuse + var_gateway var_hostname var_ipv6_method var_mac var_mtu + var_net var_ns var_pw var_ram var_tags var_tun var_unprivileged + var_verbose var_vlan var_ssh var_ssh_authorized_key + var_container_storage var_template_storage + ) + + # Ensure file exists + _ensure_default_vars + + # Find and load + local dv="$(_find_default_vars)" + load_vars_file "$dv" + + # Map verbose flag + if [[ -n "${var_verbose:-}" ]]; then + case "${var_verbose,,}" in + 1 | yes | true | on) VERBOSE="yes" ;; + *) VERBOSE="${var_verbose}" ;; + esac + fi + + # Apply and display + base_settings "$VERBOSE" + echo_default +} +``` + +--- + +### `maybe_offer_save_app_defaults()` + +**Purpose**: Offer to save current settings as app-specific defaults + +**Signature**: +```bash +maybe_offer_save_app_defaults() +``` + +**Parameters**: None + +**Returns**: None (side effects only) + +**Behavior**: + +1. After advanced installation completes +2. Offers user: "Save as App Defaults for ?" +3. If yes: + - Saves to `/usr/local/community-scripts/defaults/.vars` + - Only whitelisted variables included + - Previous defaults backed up (if exists) +4. If no: + - No action taken + +**Flow**: + +```bash +maybe_offer_save_app_defaults() { + local app_vars_path="$(get_app_defaults_path)" + + # Build current settings from memory + local new_tmp="$(_build_current_app_vars_tmp)" + + # Check if already exists + if [ -f "$app_vars_path" ]; then + # Show diff and ask: Update? Keep? View Diff? + _show_app_defaults_diff_menu "$new_tmp" "$app_vars_path" + else + # New defaults - just save + if whiptail --yesno "Save as App Defaults for $APP?" 10 60; then + mv "$new_tmp" "$app_vars_path" + chmod 644 "$app_vars_path" + fi + fi +} +``` + +--- + +### `_sanitize_value()` + +**Purpose**: Remove dangerous characters/patterns from configuration values + +**Signature**: +```bash +_sanitize_value(value) +``` + +**Parameters**: + +| Param | Type | Required | +|-------|------|----------| +| value | String | Yes | + +**Returns**: +- `0` (success) + sanitized value on stdout +- `1` (failure) + nothing if dangerous + +**Dangerous Patterns**: + +| Pattern | Threat | Example | +|---------|--------|---------| +| `$(...)` | Command substitution | `$(rm -rf /)` | +| `` ` ` `` | Command substitution | `` `whoami` `` | +| `;` | Command separator | `value; rm -rf /` | +| `&` | Background execution | `value & malicious` | +| `<(` | Process substitution | `<(cat /etc/passwd)` | + +**Implementation**: + +```bash +_sanitize_value() { + case "$1" in + *'$('* | *'`'* | *';'* | *'&'* | *'<('*) + echo "" + return 1 # Reject dangerous value + ;; + esac + echo "$1" + return 0 +} +``` + +**Usage Examples**: + +```bash +# Safe value +_sanitize_value "192.168.1.1" # Returns: 192.168.1.1 (status: 0) + +# Dangerous value +_sanitize_value "$(whoami)" # Returns: (empty) (status: 1) + +# Usage in code +if val="$(_sanitize_value "$user_input")"; then + export var_hostname="$val" +else + msg_error "Invalid value: contains dangerous characters" +fi +``` + +--- + +### `_is_whitelisted_key()` + +**Purpose**: Check if variable name is in allowed whitelist + +**Signature**: +```bash +_is_whitelisted_key(key) +``` + +**Parameters**: + +| Param | Type | Required | Example | +|-------|------|----------|---------| +| key | String | Yes | `var_cpu` | + +**Returns**: +- `0` if key is whitelisted +- `1` if key is NOT whitelisted + +**Implementation**: + +```bash +_is_whitelisted_key() { + local k="$1" + local w + for w in "${VAR_WHITELIST[@]}"; do + [ "$k" = "$w" ] && return 0 + done + return 1 +} +``` + +**Usage Examples**: + +```bash +# Check if variable can be saved +if _is_whitelisted_key "var_cpu"; then + echo "var_cpu can be saved" +fi + +# Reject unknown variables +if ! _is_whitelisted_key "var_custom"; then + msg_error "var_custom is not supported" +fi +``` + +--- + +## Variable Precedence + +### Loading Order + +When a container is being created, variables are resolved in this order: + +``` +Step 1: Read ENVIRONMENT VARIABLES + β”œβ”€ Check if var_cpu is already set in shell environment + β”œβ”€ Check if var_ram is already set + └─ ...all var_* variables + +Step 2: Load APP-SPECIFIC DEFAULTS + β”œβ”€ Check if /usr/local/community-scripts/defaults/pihole.vars exists + β”œβ”€ Load all var_* from that file + └─ These override built-ins but NOT environment variables + +Step 3: Load USER GLOBAL DEFAULTS + β”œβ”€ Check if /usr/local/community-scripts/default.vars exists + β”œβ”€ Load all var_* from that file + └─ These override built-ins but NOT app-specific + +Step 4: Use BUILT-IN DEFAULTS + └─ Hardcoded in script (lowest priority) +``` + +### Precedence Examples + +**Example 1: Environment Variable Wins** +```bash +# Shell environment has highest priority +$ export var_cpu=16 +$ bash pihole-install.sh + +# Result: Container gets 16 cores +# (ignores app defaults, user defaults, built-ins) +``` + +**Example 2: App Defaults Override User Defaults** +```bash +# User Defaults: var_cpu=4 +# App Defaults: var_cpu=2 +$ bash pihole-install.sh + +# Result: Container gets 2 cores +# (app-specific setting takes precedence) +``` + +**Example 3: All Defaults Missing (Built-ins Used)** +```bash +# No environment variables set +# No app defaults file +# No user defaults file +$ bash pihole-install.sh + +# Result: Uses built-in defaults +# (var_cpu might be 2 by default) +``` + +### Implementation in Code + +```bash +# Typical pattern in build.func + +base_settings() { + # Priority 1: Environment variables (already set if export used) + CT_TYPE=${var_unprivileged:-"1"} # Use existing or default + + # Priority 2: Load app defaults (may override above) + if [ -f "$(get_app_defaults_path)" ]; then + load_vars_file "$(get_app_defaults_path)" + fi + + # Priority 3: Load user defaults + if [ -f "/usr/local/community-scripts/default.vars" ]; then + load_vars_file "/usr/local/community-scripts/default.vars" + fi + + # Priority 4: Apply built-in defaults (lowest) + CORE_COUNT=${var_cpu:-"${APP_CPU_DEFAULT:-2}"} + RAM_SIZE=${var_ram:-"${APP_RAM_DEFAULT:-1024}"} + + # Result: var_cpu has been set through precedence chain +} +``` + +--- + +## Data Flow Diagrams + +### Installation Flow: Advanced Settings + +``` +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ Start Scriptβ”‚ +β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + v +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ Display Installation Mode β”‚ +β”‚ Menu (5 options) β”‚ +β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ User selects "Advanced Settings" + v +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ Call: base_settings() β”‚ +β”‚ (Apply built-in defaults) β”‚ +β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + v +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ Call: advanced_settings() β”‚ +β”‚ (Show 19-step wizard) β”‚ +β”‚ - Ask CPU, RAM, Disk, Network... β”‚ +β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + v +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ Show Summary β”‚ +β”‚ Review all chosen values β”‚ +β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ User confirms + v +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ Create Container β”‚ +β”‚ Using current variable values β”‚ +β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + v +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ Installation Complete β”‚ +β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + v +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ Offer: Save as App Defaults? β”‚ +β”‚ (Save current settings) β”‚ +β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β”œβ”€ YES β†’ Save to defaults/.vars + β”‚ + └─ NO β†’ Exit +``` + +### Variable Resolution Flow + +``` +CONTAINER CREATION STARTED + β”‚ + v + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ Check ENVIRONMENT β”‚ + β”‚ for var_cpu, var_..β”‚ + β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ Found? Use them (Priority 1) + β”‚ Not found? Continue... + v + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ Load App Defaults β”‚ + β”‚ /defaults/.vars β”‚ + β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ File exists? Parse & load (Priority 2) + β”‚ Not found? Continue... + v + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ Load User Defaults β”‚ + β”‚ /default.vars β”‚ + β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ File exists? Parse & load (Priority 3) + β”‚ Not found? Continue... + v + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ Use Built-in Defaults β”‚ + β”‚ (Hardcoded values) β”‚ + β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + v + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ All Variables Resolved β”‚ + β”‚ Ready for container β”‚ + β”‚ creation β”‚ + β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +``` + +--- + +## Security Model + +### Threat Model + +| Threat | Mitigation | +|--------|-----------| +| **Arbitrary Code Execution** | No `source` or `eval`; manual parsing only | +| **Variable Injection** | Whitelist of allowed variable names | +| **Command Substitution** | `_sanitize_value()` blocks `$()`, backticks, etc. | +| **Path Traversal** | Files locked to `/usr/local/community-scripts/` | +| **Permission Escalation** | Files created with restricted permissions | +| **Information Disclosure** | Sensitive variables not logged | + +### Security Controls + +#### 1. Input Validation + +```bash +# Only specific variables allowed +if ! _is_whitelisted_key "$key"; then + skip_this_variable +fi + +# Values sanitized +if ! val="$(_sanitize_value "$value")"; then + reject_entire_line +fi +``` + +#### 2. Safe File Parsing + +```bash +# ❌ DANGEROUS (OLD) +source /path/to/config.conf +# Could execute: rm -rf / or any code + +# βœ… SAFE (NEW) +load_vars_file "/path/to/config.conf" +# Only reads var_name=value pairs, no execution +``` + +#### 3. Whitelisting + +```bash +# Only these variables can be configured +var_cpu, var_ram, var_disk, var_brg, ... +var_hostname, var_pw, var_ssh, ... + +# NOT allowed: +var_malicious, var_hack, custom_var, ... +``` + +#### 4. Value Constraints + +```bash +# No command injection patterns +if [[ "$value" =~ ($|`|;|&|<\() ]]; then + reject_value +fi +``` + +--- + +## Implementation Details + +### Module: `build.func` + +**Load Order** (in actual scripts): +1. `#!/usr/bin/env bash` - Shebang +2. `source /dev/stdin <<<$(curl ... api.func)` - API functions +3. `source /dev/stdin <<<$(curl ... build.func)` - Build functions +4. `variables()` - Initialize variables +5. `check_root()` - Security check +6. `install_script()` - Main flow + +**Key Sections**: + +```bash +# Section 1: Initialization & Variables +- variables() +- NSAPP, var_install, INTEGER pattern, etc. + +# Section 2: Storage Management +- storage_selector() +- ensure_storage_selection_for_vars_file() + +# Section 3: Base Settings +- base_settings() # Apply defaults to all var_* +- echo_default() # Display current settings + +# Section 4: Variable Loading +- load_vars_file() # Safe parsing +- _is_whitelisted_key() # Validation +- _sanitize_value() # Threat mitigation + +# Section 5: Defaults Management +- default_var_settings() # Load user defaults +- get_app_defaults_path() # Get app defaults path +- maybe_offer_save_app_defaults() # Save option + +# Section 6: Installation Flow +- install_script() # Main entry point +- advanced_settings() # 19-step wizard +``` + +### Regex Patterns Used + +| Pattern | Purpose | Example Match | +|---------|---------|---| +| `^[0-9]+([.][0-9]+)?$` | Integer validation | `4`, `192.168` | +| `^var_[a-z_]+$` | Variable name | `var_cpu`, `var_ssh` | +| `*'$('*` | Command substitution | `$(whoami)` | +| `*\`*` | Backtick substitution | `` `cat /etc/passwd` `` | + +--- + +## Appendix: Migration Reference + +### Old Pattern (Deprecated) + +```bash +# ❌ OLD: config-file.func +source config-file.conf # Executes arbitrary code +if [ "$USE_DEFAULTS" = "yes" ]; then + apply_settings_directly +fi +``` + +### New Pattern (Current) + +```bash +# βœ… NEW: load_vars_file() +if load_vars_file "$(get_app_defaults_path)"; then + echo "Settings loaded securely" +fi +``` + +### Function Mapping + +| Old | New | Location | +|-----|-----|----------| +| `read_config()` | `load_vars_file()` | build.func | +| `write_config()` | `_build_current_app_vars_tmp()` | build.func | +| None | `maybe_offer_save_app_defaults()` | build.func | +| None | `get_app_defaults_path()` | build.func | + +--- + +**End of Technical Reference** diff --git a/docs/api/README.md b/docs/api/README.md new file mode 100644 index 000000000..4d0194fee --- /dev/null +++ b/docs/api/README.md @@ -0,0 +1,146 @@ +# API Integration Documentation (/api) + +This directory contains comprehensive documentation for API integration and the `/api` directory. + +## Overview + +The `/api` directory contains the Proxmox Community Scripts API backend for diagnostic reporting, telemetry, and analytics integration. + +## Key Components + +### Main API Service +Located in `/api/main.go`: +- RESTful API for receiving telemetry data +- Installation statistics tracking +- Error reporting and analytics +- Performance monitoring + +### Integration with Scripts +The API is integrated into all installation scripts via `api.func`: +- Sends installation start/completion events +- Reports errors and exit codes +- Collects anonymous usage statistics +- Enables project analytics + +## Documentation Structure + +API documentation covers: +- API endpoint specifications +- Integration methods +- Data formats and schemas +- Error handling +- Privacy and data handling + +## Key Resources + +- **[misc/api.func/](../misc/api.func/)** - API function library documentation +- **[misc/api.func/README.md](../misc/api.func/README.md)** - Quick reference +- **[misc/api.func/API_FUNCTIONS_REFERENCE.md](../misc/api.func/API_FUNCTIONS_REFERENCE.md)** - Complete function reference + +## API Functions + +The `api.func` library provides: + +### `post_to_api()` +Send container installation data to API. + +**Usage**: +```bash +post_to_api CTID STATUS APP_NAME +``` + +### `post_update_to_api()` +Report application update status. + +**Usage**: +```bash +post_update_to_api CTID APP_NAME VERSION +``` + +### `get_error_description()` +Get human-readable error description from exit code. + +**Usage**: +```bash +ERROR_DESC=$(get_error_description EXIT_CODE) +``` + +## API Integration Points + +### In Container Creation (`ct/AppName.sh`) +- Called by build.func to report container creation +- Sends initial container setup data +- Reports success or failure + +### In Installation Scripts (`install/appname-install.sh`) +- Called at start of installation +- Called on installation completion +- Called on error conditions + +### Data Collected +- Container/VM ID +- Application name and version +- Installation duration +- Success/failure status +- Error codes (if failure) +- Anonymous usage metrics + +## Privacy + +All API data: +- βœ… Anonymous (no personal data) +- βœ… Aggregated for statistics +- βœ… Used only for project improvement +- βœ… No tracking of user identities +- βœ… Can be disabled if desired + +## API Architecture + +``` +Installation Scripts + β”‚ + β”œβ”€ Call: api.func functions + β”‚ + └─ POST to: https://api.community-scripts.org + β”‚ + β”œβ”€ Receives data + β”œβ”€ Validates format + β”œβ”€ Stores metrics + └─ Aggregates statistics + β”‚ + └─ Used for: + β”œβ”€ Download tracking + β”œβ”€ Error trending + β”œβ”€ Feature usage stats + └─ Project health monitoring +``` + +## Common API Tasks + +- **Enable API reporting** β†’ Built-in by default, no configuration needed +- **Disable API** β†’ Set `api_disable="yes"` before running +- **View API data** β†’ Visit https://community-scripts.org/stats +- **Report API errors** β†’ [GitHub Issues](https://github.com/community-scripts/ProxmoxVE/issues) + +## Debugging API Issues + +If API calls fail: +1. Check internet connectivity +2. Verify API endpoint availability +3. Review error codes in [EXIT_CODES.md](../EXIT_CODES.md) +4. Check API function logs +5. Report issues on GitHub + +## API Endpoint + +**Base URL**: `https://api.community-scripts.org` + +**Endpoints**: +- `POST /install` - Report container installation +- `POST /update` - Report application update +- `GET /stats` - Public statistics + +--- + +**Last Updated**: December 2025 +**Maintainers**: community-scripts team diff --git a/docs/contribution/CODE-AUDIT.md b/docs/contribution/CODE-AUDIT.md new file mode 100644 index 000000000..17a1ff4a4 --- /dev/null +++ b/docs/contribution/CODE-AUDIT.md @@ -0,0 +1,14 @@ +
+ +
+

Exploring the Scripts and Steps Involved in an Application LXC Installation

+ +1) [adguard.sh](https://github.com/community-scripts/ProxmoxVE/blob/main/ct/adguard.sh): This script collects system parameters. (Also holds the function to update the application.) +2) [build.func](https://github.com/community-scripts/ProxmoxVE/blob/main/misc/build.func): Adds user settings and integrates collected information. +3) [create_lxc.sh](https://github.com/community-scripts/ProxmoxVE/blob/main/misc/create_lxc.sh): Constructs the LXC container. +4) [adguard-install.sh](https://github.com/community-scripts/ProxmoxVE/blob/main/install/adguard-install.sh): Executes functions from [install.func](https://github.com/community-scripts/ProxmoxVE/blob/main/misc/install.func), and installs the application. +5) [adguard.sh](https://github.com/community-scripts/ProxmoxVE/blob/main/ct/adguard.sh) (again): To display the completion message. + +The installation process uses reusable scripts: [build.func](https://github.com/community-scripts/ProxmoxVE/blob/main/misc/build.func), [create_lxc.sh](https://github.com/community-scripts/ProxmoxVE/blob/main/misc/create_lxc.sh), and [install.func](https://github.com/community-scripts/ProxmoxVE/blob/main/misc/install.func), which are not specific to any particular application. + +To gain a better understanding, focus on reviewing [adguard-install.sh](https://github.com/community-scripts/ProxmoxVE/blob/main/install/adguard-install.sh). This script contains the commands and configurations for installing and configuring AdGuard Home within the LXC container. diff --git a/docs/contribution/CONTRIBUTING.md b/docs/contribution/CONTRIBUTING.md new file mode 100644 index 000000000..f5a46fcd1 --- /dev/null +++ b/docs/contribution/CONTRIBUTING.md @@ -0,0 +1,106 @@ + +# Community Scripts Contribution Guide + +## **Welcome to the communty-scripts Repository!** + +πŸ“œ These documents outline the essential coding standards for all our scripts and JSON files. Adhering to these standards ensures that our codebase remains consistent, readable, and maintainable. By following these guidelines, we can improve collaboration, reduce errors, and enhance the overall quality of our project. + +### Why Coding Standards Matter + +Coding standards are crucial for several reasons: + +1. **Consistency**: Consistent code is easier to read, understand, and maintain. It helps new team members quickly get up to speed and reduces the learning curve. +2. **Readability**: Clear and well-structured code is easier to debug and extend. It allows developers to quickly identify and fix issues. +3. **Maintainability**: Code that follows a standard structure is easier to refactor and update. It ensures that changes can be made with minimal risk of introducing new bugs. +4. **Collaboration**: When everyone follows the same standards, it becomes easier to collaborate on code. It reduces friction and misunderstandings during code reviews and merges. + +### Scope of These Documents + +These documents cover the coding standards for the following types of files in our project: + +- **`install/$AppName-install.sh` Scripts**: These scripts are responsible for the installation of applications. +- **`ct/$AppName.sh` Scripts**: These scripts handle the creation and updating of containers. +- **`json/$AppName.json`**: These files store structured data and are used for the website. + +Each section provides detailed guidelines on various aspects of coding, including shebang usage, comments, variable naming, function naming, indentation, error handling, command substitution, quoting, script structure, and logging. Additionally, examples are provided to illustrate the application of these standards. + +By following the coding standards outlined in this document, we ensure that our scripts and JSON files are of high quality, making our project more robust and easier to manage. Please refer to this guide whenever you create or update scripts and JSON files to maintain a high standard of code quality across the project. πŸ“šπŸ” + +Let's work together to keep our codebase clean, efficient, and maintainable! πŸ’ͺπŸš€ + + +## Getting Started + +Before contributing, please ensure that you have the following setup: + +1. **Visual Studio Code** (recommended for script development) +2. **Recommended VS Code Extensions:** + - [Shell Syntax](https://marketplace.visualstudio.com/items?itemName=bmalehorn.shell-syntax) + - [ShellCheck](https://marketplace.visualstudio.com/items?itemName=timonwong.shellcheck) + - [Shell Format](https://marketplace.visualstudio.com/items?itemName=foxundermoon.shell-format) + +### Important Notes +- Use [AppName.sh](https://github.com/community-scripts/ProxmoxVE/blob/main/.github/CONTRIBUTOR_AND_GUIDES/ct/AppName.sh) and [AppName-install.sh](https://github.com/community-scripts/ProxmoxVE/blob/main/.github/CONTRIBUTOR_AND_GUIDES/install/AppName-install.sh) as templates when creating new scripts. + +--- + +# πŸš€ The Application Script (ct/AppName.sh) + +- You can find all coding standards, as well as the structure for this file [here](https://github.com/community-scripts/ProxmoxVE/blob/main/.github/CONTRIBUTOR_AND_GUIDES/ct/AppName.md). +- These scripts are responsible for container creation, setting the necessary variables and handling the update of the application once installed. + +--- + +# πŸ›  The Installation Script (install/AppName-install.sh) + +- You can find all coding standards, as well as the structure for this file [here](https://github.com/community-scripts/ProxmoxVE/blob/main/.github/CONTRIBUTOR_AND_GUIDES/install/AppName-install.md). +- These scripts are responsible for the installation of the application. + +--- + +## πŸš€ Building Your Own Scripts + +Start with the [template script](https://github.com/community-scripts/ProxmoxVE/blob/main/.github/CONTRIBUTOR_AND_GUIDES/install/AppName-install.sh) + +--- + +## 🀝 Contribution Process + +### 1. Fork the repository +Fork to your GitHub account + +### 2. Clone your fork on your local environment +```bash +git clone https://github.com/yourUserName/ForkName +``` + +### 3. Create a new branch +```bash +git switch -c your-feature-branch +``` + +### 4. Change paths in build.func install.func and AppName.sh +To be able to develop from your own branch you need to change `https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main` to `https://raw.githubusercontent.com/[USER]/[REPOSITORY]/refs/heads/[BRANCH]`. You need to make this change atleast in misc/build.func misc/install.func and in your ct/AppName.sh. This change is only for testing. Before opening a Pull Request you should change this line change all this back to point to `https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main`. + +### 4. Commit changes (without build.func and install.func!) +```bash +git commit -m "Your commit message" +``` + +### 5. Push to your fork +```bash +git push origin your-feature-branch +``` + +### 6. Create a Pull Request +Open a Pull Request from your feature branch to the main repository branch. You must only include your **$AppName.sh**, **$AppName-install.sh** and **$AppName.json** files in the pull request. + +--- + +## πŸ“š Pages + +- [CT Template: AppName.sh](https://github.com/community-scripts/ProxmoxVE/blob/main/.github/CONTRIBUTOR_AND_GUIDES/ct/AppName.sh) +- [Install Template: AppName-install.sh](https://github.com/community-scripts/ProxmoxVE/blob/main/.github/CONTRIBUTOR_AND_GUIDES/install/AppName-install.sh) +- [JSON Template: AppName.json](https://github.com/community-scripts/ProxmoxVE/blob/main/.github/CONTRIBUTOR_AND_GUIDES/json/AppName.json) + + diff --git a/docs/contribution/FORK_SETUP.md b/docs/contribution/FORK_SETUP.md new file mode 100644 index 000000000..3fa3ab71c --- /dev/null +++ b/docs/contribution/FORK_SETUP.md @@ -0,0 +1,186 @@ +# 🍴 Fork Setup Guide + +**Just forked ProxmoxVE? Run this first!** + +## Quick Start + +```bash +# Clone your fork +git clone https://github.com/YOUR_USERNAME/ProxmoxVE.git +cd ProxmoxVE + +# Run setup script (auto-detects your username from git) +bash setup-fork.sh +``` + +That's it! βœ… + +--- + +## What Does It Do? + +The `setup-fork.sh` script automatically: + +1. **Detects** your GitHub username from git config +2. **Updates** 22 hardcoded links in documentation to point to your fork +3. **Creates** `.git-setup-info` with recommended git workflows +4. **Backs up** all modified files (*.backup) + +--- + +## Usage + +### Auto-Detect (Recommended) +```bash +bash setup-fork.sh +``` +Automatically reads your GitHub username from `git remote origin url` + +### Specify Username +```bash +bash setup-fork.sh john +``` +Updates links to `github.com/john/ProxmoxVE` + +### Custom Repository Name +```bash +bash setup-fork.sh john my-fork +``` +Updates links to `github.com/john/my-fork` + +--- + +## What Gets Updated? + +The script updates these documentation files: +- `docs/CONTRIBUTION_GUIDE.md` (4 links) +- `docs/README.md` (1 link) +- `docs/INDEX.md` (3 links) +- `docs/EXIT_CODES.md` (2 links) +- `docs/DEFAULTS_SYSTEM_GUIDE.md` (2 links) +- `docs/api/README.md` (1 link) +- `docs/APP-ct.md` (1 link) +- `docs/APP-install.md` (1 link) +- `docs/alpine-install.func.md` (2 links) +- `docs/install.func.md` (1 link) +- And code examples in documentation + +--- + +## After Setup + +1. **Review changes** + ```bash + git diff docs/ + ``` + +2. **Read git workflow tips** + ```bash + cat .git-setup-info + ``` + +3. **Start contributing** + ```bash + git checkout -b feature/my-app + # Make your changes... + git commit -m "feat: add my awesome app" + ``` + +4. **Follow the guide** + ```bash + cat docs/CONTRIBUTION_GUIDE.md + ``` + +--- + +## Common Workflows + +### Keep Your Fork Updated +```bash +# Add upstream if you haven't already +git remote add upstream https://github.com/community-scripts/ProxmoxVE.git + +# Get latest from upstream +git fetch upstream +git rebase upstream/main +git push origin main +``` + +### Create a Feature Branch +```bash +git checkout -b feature/docker-improvements +# Make changes... +git push origin feature/docker-improvements +# Then create PR on GitHub +``` + +### Sync Before Contributing +```bash +git fetch upstream +git rebase upstream/main +git push -f origin main # Update your fork's main +git checkout -b feature/my-feature +``` + +--- + +## Troubleshooting + +### "Git is not installed" or "not a git repository" +```bash +# Make sure you cloned the repo first +git clone https://github.com/YOUR_USERNAME/ProxmoxVE.git +cd ProxmoxVE +bash setup-fork.sh +``` + +### "Could not auto-detect GitHub username" +```bash +# Your git origin URL isn't set up correctly +git remote -v +# Should show your fork URL, not community-scripts + +# Fix it: +git remote set-url origin https://github.com/YOUR_USERNAME/ProxmoxVE.git +bash setup-fork.sh +``` + +### "Permission denied" +```bash +# Make script executable +chmod +x setup-fork.sh +bash setup-fork.sh +``` + +### Reverted Changes by Accident? +```bash +# Backups are created automatically +git checkout docs/*.backup +# Or just re-run setup-fork.sh +``` + +--- + +## Next Steps + +1. βœ… Run `bash setup-fork.sh` +2. πŸ“– Read [docs/CONTRIBUTION_GUIDE.md](docs/CONTRIBUTION_GUIDE.md) +3. 🍴 Choose your contribution path: + - **Containers** β†’ [docs/ct/README.md](docs/ct/README.md) + - **Installation** β†’ [docs/install/README.md](docs/install/README.md) + - **VMs** β†’ [docs/vm/README.md](docs/vm/README.md) + - **Tools** β†’ [docs/tools/README.md](docs/tools/README.md) +4. πŸ’» Create your feature branch and contribute! + +--- + +## Questions? + +- **Fork Setup Issues?** β†’ See [Troubleshooting](#troubleshooting) above +- **How to Contribute?** β†’ [docs/CONTRIBUTION_GUIDE.md](docs/CONTRIBUTION_GUIDE.md) +- **Git Workflows?** β†’ `cat .git-setup-info` +- **Project Structure?** β†’ [docs/README.md](docs/README.md) + +--- + +**Happy Contributing! πŸš€** diff --git a/docs/contribution/GUIDE.md b/docs/contribution/GUIDE.md new file mode 100644 index 000000000..2d89fd31a --- /dev/null +++ b/docs/contribution/GUIDE.md @@ -0,0 +1,1053 @@ +# 🎯 **ProxmoxVE Contribution Guide** + +**Everything you need to know to contribute to ProxmoxVE** + +> **Last Updated**: December 2025 +> **Difficulty**: Beginner β†’ Advanced +> **Time to Setup**: 15 minutes +> **Time to Contribute**: 1-3 hours + +--- + +## πŸ“‹ Table of Contents + +- [Quick Start](#quick-start) +- [Repository Structure](#repository-structure) +- [Development Setup](#development-setup) +- [Creating New Applications](#creating-new-applications) +- [Updating Existing Applications](#updating-existing-applications) +- [Code Standards](#code-standards) +- [Testing Your Changes](#testing-your-changes) +- [Submitting a Pull Request](#submitting-a-pull-request) +- [Troubleshooting](#troubleshooting) +- [FAQ](#faq) + +--- + +## Quick Start + +### Setup Your Fork (First Time Only) + +```bash +# 1. Fork the repository on GitHub +# Visit: https://github.com/community-scripts/ProxmoxVE +# Click: Fork (top right) + +# 2. Clone your fork +git clone https://github.com/YOUR_USERNAME/ProxmoxVE.git +cd ProxmoxVE + +# 3. Run fork setup script (automatically configures everything) +bash setup-fork.sh +# This auto-detects your username and updates all documentation links + +# 4. Read the git workflow tips +cat .git-setup-info +``` + +### 60 Seconds to First Contribution + +```bash +# 1. Create feature branch +git checkout -b add/my-awesome-app + +# 2. Create application scripts +cp ct/example.sh ct/myapp.sh +cp install/example-install.sh install/myapp-install.sh + +# 3. Edit your scripts +nano ct/myapp.sh +nano install/myapp-install.sh + +# 4. Test locally +bash ct/myapp.sh # Will prompt for container creation + +# 5. Commit and push +git add ct/myapp.sh install/myapp-install.sh +git commit -m "feat: add MyApp container" +git push origin add/my-awesome-app + +# 6. Open Pull Request on GitHub +# Click: New Pull Request (GitHub will show this automatically) + +# 7. Keep your fork updated +git fetch upstream +git rebase upstream/main +``` + +**πŸ’‘ Tip**: See `../FORK_SETUP.md` for detailed fork setup and troubleshooting + +--- + +## Repository Structure + +### Top-Level Organization + +``` +ProxmoxVE/ +β”œβ”€β”€ ct/ # πŸ—οΈ Container creation scripts (host-side) +β”‚ β”œβ”€β”€ pihole.sh +β”‚ β”œβ”€β”€ docker.sh +β”‚ └── ... (40+ applications) +β”‚ +β”œβ”€β”€ install/ # πŸ› οΈ Installation scripts (container-side) +β”‚ β”œβ”€β”€ pihole-install.sh +β”‚ β”œβ”€β”€ docker-install.sh +β”‚ └── ... (40+ applications) +β”‚ +β”œβ”€β”€ vm/ # πŸ’Ύ VM creation scripts +β”‚ β”œβ”€β”€ ubuntu2404-vm.sh +β”‚ β”œβ”€β”€ debian-vm.sh +β”‚ └── ... (15+ operating systems) +β”‚ +β”œβ”€β”€ misc/ # πŸ“¦ Shared function libraries +β”‚ β”œβ”€β”€ build.func # Main orchestrator (3800+ lines) +β”‚ β”œβ”€β”€ core.func # UI/utilities +β”‚ β”œβ”€β”€ error_handler.func # Error management +β”‚ β”œβ”€β”€ tools.func # Tool installation +β”‚ β”œβ”€β”€ install.func # Container setup +β”‚ β”œβ”€β”€ cloud-init.func # VM configuration +β”‚ β”œβ”€β”€ api.func # Telemetry +β”‚ β”œβ”€β”€ alpine-install.func # Alpine-specific +β”‚ └── alpine-tools.func # Alpine tools +β”‚ +β”œβ”€β”€ docs/ # πŸ“š Documentation +β”‚ β”œβ”€β”€ UPDATED_APP-ct.md # Container script guide +β”‚ β”œβ”€β”€ UPDATED_APP-install.md # Install script guide +β”‚ └── CONTRIBUTING.md # (This file!) +β”‚ +β”œβ”€β”€ tools/ # πŸ”§ Proxmox management tools +β”‚ └── pve/ +β”‚ +└── README.md # Project overview +``` + +### Naming Conventions + +``` +Container Script: ct/AppName.sh +Installation Script: install/appname-install.sh +Defaults: defaults/appname.vars +Update Script: /usr/bin/update (inside container) + +Examples: + ct/pihole.sh β†’ install/pihole-install.sh + ct/docker.sh β†’ install/docker-install.sh + ct/nextcloud-vm.sh β†’ install/nextcloud-vm-install.sh +``` + +**Rules**: +- Container script name: **Title Case** (PiHole, Docker, NextCloud) +- Install script name: **lowercase** with **hyphens** (pihole-install, docker-install) +- Must match: `ct/AppName.sh` ↔ `install/appname-install.sh` +- Directory names: lowercase (always) +- Variable names: lowercase (except APP constant) + +--- + +## Development Setup + +### Prerequisites + +1. **Proxmox VE 8.0+** with at least: + - 4 CPU cores + - 8 GB RAM + - 50 GB disk space + - Ubuntu 20.04 / Debian 11+ on host + +2. **Git** installed + ```bash + apt-get install -y git + ``` + +3. **Text Editor** (VS Code recommended) + ```bash + # VS Code extensions: + # - Bash IDE + # - Shellcheck + # - Markdown All in One + ``` + +### Local Development Workflow + +#### Option A: Development Fork (Recommended) + +```bash +# 1. Fork on GitHub (one-time) +# Visit: https://github.com/community-scripts/ProxmoxVE +# Click: Fork + +# 2. Clone your fork +git clone https://github.com/YOUR_USERNAME/ProxmoxVE.git +cd ProxmoxVE + +# 3. Add upstream remote for updates +git remote add upstream https://github.com/community-scripts/ProxmoxVE.git + +# 4. Create feature branch +git checkout -b feat/add-myapp + +# 5. Make changes +# ... edit files ... + +# 6. Keep fork updated +git fetch upstream +git rebase upstream/main + +# 7. Push and open PR +git push origin feat/add-myapp +``` + +#### Option B: Local Testing on Proxmox Host + +```bash +# 1. SSH into Proxmox host +ssh root@192.168.1.100 + +# 2. Download your script +curl -O https://raw.githubusercontent.com/YOUR_USERNAME/ProxmoxVE/feat/myapp/ct/myapp.sh + +# 3. Make it executable +chmod +x myapp.sh + +# 4. Update URLs to your fork +# Edit: curl -s https://raw.githubusercontent.com/YOUR_USERNAME/ProxmoxVE/feat/myapp/... + +# 5. Run and test +bash myapp.sh + +# 6. If container created successfully, script is working! +``` + +#### Option C: Docker Testing (Without Proxmox) + +```bash +# You can test script syntax/functionality locally +# Note: Won't fully test (no Proxmox, no actual container) + +# Run ShellCheck +shellcheck ct/myapp.sh +shellcheck install/myapp-install.sh + +# Syntax check +bash -n ct/myapp.sh +bash -n install/myapp-install.sh +``` + +--- + +## Creating New Applications + +### Step 1: Choose Your Template + +**For Simple Web Apps** (Node.js, Python, PHP): +```bash +cp ct/example.sh ct/myapp.sh +cp install/example-install.sh install/myapp-install.sh +``` + +**For Database Apps** (PostgreSQL, MongoDB): +```bash +cp ct/docker.sh ct/myapp.sh # Use Docker container +# OR manual setup for more control +``` + +**For Alpine Linux Apps** (lightweight): +```bash +# Use ct/alpine.sh as reference +# Edit install script to use Alpine packages (apk not apt) +``` + +### Step 2: Update Container Script + +**File**: `ct/myapp.sh` + +```bash +#!/usr/bin/env bash +source <(curl -fsSL https://raw.githubusercontent.com/YOUR_USERNAME/ProxmoxVE/feat/myapp/misc/build.func) + +# Update these: +APP="MyAwesomeApp" # Display name +var_tags="category;tag2;tag3" # Max 3-4 tags +var_cpu="2" # Realistic CPU cores +var_ram="2048" # Min RAM needed (MB) +var_disk="10" # Min disk (GB) +var_os="debian" # OS type +var_version="12" # OS version +var_unprivileged="1" # Security (1=unprivileged) + +header_info "$APP" +variables +color +catch_errors + +function update_script() { + header_info + check_container_storage + check_container_resources + + if [[ ! -d /opt/myapp ]]; then + msg_error "No ${APP} Installation Found!" + exit + fi + + # Get latest version + RELEASE=$(curl -fsSL https://api.github.com/repos/user/repo/releases/latest | \ + grep "tag_name" | awk '{print substr($2, 2, length($2)-3)}') + + if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then + msg_info "Updating ${APP} to v${RELEASE}" + # ... update logic ... + echo "${RELEASE}" > /opt/${APP}_version.txt + msg_ok "Updated ${APP}" + else + msg_ok "No update required. ${APP} is already at v${RELEASE}." + fi + exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}" +echo -e "${INFO}${YW} Access it using the following URL:${CL}" +echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:PORT${CL}" +``` + +**Checklist**: +- [ ] APP variable matches filename +- [ ] var_tags semicolon-separated (no spaces) +- [ ] Realistic CPU/RAM/disk values +- [ ] update_script() implemented +- [ ] Correct OS and version +- [ ] Success message with access URL + +### Step 3: Update Installation Script + +**File**: `install/myapp-install.sh` + +```bash +#!/usr/bin/env bash +# Copyright (c) 2021-2025 community-scripts ORG +# Author: YourUsername +# License: MIT +# Source: https://github.com/example/myapp + +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y \ + curl \ + wget \ + git \ + build-essential +msg_ok "Installed Dependencies" + +msg_info "Setting up Node.js" +NODE_VERSION="22" setup_nodejs +msg_ok "Node.js installed" + +msg_info "Downloading Application" +cd /opt +wget -q "https://github.com/user/repo/releases/download/v1.0.0/myapp.tar.gz" +tar -xzf myapp.tar.gz +rm -f myapp.tar.gz +msg_ok "Application installed" + +echo "1.0.0" > /opt/${APP}_version.txt + +motd_ssh +customize +cleanup_lxc +``` + +**Checklist**: +- [ ] Functions loaded from `$FUNCTIONS_FILE_PATH` +- [ ] All installation phases present (deps, tools, app, config, cleanup) +- [ ] Using `$STD` for output suppression +- [ ] Version file saved +- [ ] Final cleanup with `cleanup_lxc` +- [ ] No hardcoded versions (use GitHub API) + +### Step 4: Create ASCII Header (Optional) + +**File**: `ct/headers/myapp` + +``` +╔═══════════════════════════════════════╗ +β•‘ β•‘ +β•‘ πŸŽ‰ MyAwesomeApp πŸŽ‰ β•‘ +β•‘ β•‘ +β•‘ Your app is being installed... β•‘ +β•‘ β•‘ +β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β• +``` + +Save in: `ct/headers/myapp` (no extension) + +### Step 5: Create Defaults File (Optional) + +**File**: `defaults/myapp.vars` + +```bash +# Default configuration for MyAwesomeApp +var_cpu=4 +var_ram=4096 +var_disk=15 +var_hostname=myapp-container +var_timezone=UTC +``` + +--- + +## Updating Existing Applications + +### Step 1: Identify What Changed + +```bash +# Check logs or GitHub releases +curl -fsSL https://api.github.com/repos/app/repo/releases/latest | jq '.' + +# Review breaking changes +# Update dependencies if needed +``` + +### Step 2: Update Installation Script + +```bash +# Edit: install/existingapp-install.sh + +# 1. Update version (if hardcoded) +RELEASE="2.0.0" + +# 2. Update package dependencies (if any changed) +$STD apt-get install -y newdependency + +# 3. Update configuration (if format changed) +# Update sed replacements or config files + +# 4. Test thoroughly before committing +``` + +### Step 3: Update Update Function (if applicable) + +```bash +# Edit: ct/existingapp.sh β†’ update_script() + +# 1. Update GitHub API URL if repo changed +RELEASE=$(curl -fsSL https://api.github.com/repos/user/repo/releases/latest | ...) + +# 2. Update backup/restore logic (if structure changed) +# 3. Update cleanup paths + +# 4. Test update on existing installation +``` + +### Step 4: Document Your Changes + +```bash +# Add comment at top of script +# Co-Author: YourUsername +# Updated: YYYY-MM-DD - Description of changes +``` + +--- + +## Code Standards + +### Bash Style Guide + +#### Variable Naming + +```bash +# βœ… Good +APP="MyApp" # Constants (UPPERCASE) +var_cpu="2" # Configuration (var_*) +container_id="100" # Local variables (lowercase) +DB_PASSWORD="secret" # Environment-like (UPPERCASE) + +# ❌ Bad +myapp="MyApp" # Inconsistent +VAR_CPU="2" # Wrong convention +containerid="100" # Unclear purpose +``` + +#### Function Naming + +```bash +# βœ… Good +function setup_database() { } # Descriptive +function check_version() { } # Verb-noun pattern +function install_dependencies() { } # Clear action + +# ❌ Bad +function setup() { } # Too vague +function db_setup() { } # Inconsistent pattern +function x() { } # Cryptic +``` + +#### Quoting + +```bash +# βœ… Good +echo "${APP}" # Always quote variables +if [[ "$var" == "value" ]]; then # Use [[ ]] for conditionals +echo "Using $var in string" # Variables in double quotes + +# ❌ Bad +echo $APP # Unquoted variables +if [ "$var" = "value" ]; then # Use [[ ]] instead +echo 'Using $var in string' # Single quotes prevent expansion +``` + +#### Command Formatting + +```bash +# βœ… Good: Multiline for readability +$STD apt-get install -y \ + package1 \ + package2 \ + package3 + +# βœ… Good: Complex commands with variables +if ! wget -q "https://example.com/${file}"; then + msg_error "Failed to download" + exit 1 +fi + +# ❌ Bad: Too long on one line +$STD apt-get install -y package1 package2 package3 package4 package5 package6 + +# ❌ Bad: No error checking +wget https://example.com/file +``` + +#### Error Handling + +```bash +# βœ… Good: Check critical commands +if ! some_command; then + msg_error "Command failed" + exit 1 +fi + +# βœ… Good: Use catch_errors for automatic trapping +catch_errors + +# ❌ Bad: Silently ignore failures +some_command || true +some_command 2>/dev/null + +# ❌ Bad: Unclear what failed +if ! (cmd1 && cmd2 && cmd3); then + msg_error "Something failed" +fi +``` + +### Documentation Standards + +#### Header Comments + +```bash +#!/usr/bin/env bash +# Copyright (c) 2021-2025 community-scripts ORG +# Author: YourUsername +# Co-Author: AnotherAuthor (for collaborative work) +# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE +# Source: https://github.com/app/repo +# Description: Brief description of what this script does +``` + +#### Inline Comments + +```bash +# βœ… Good: Explain WHY, not WHAT +# Use alphanumeric only to avoid shell escaping issues +DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13) + +# βœ… Good: Comment complex logic +# Detect if running Alpine vs Debian for proper package manager +if grep -qi 'alpine' /etc/os-release; then + PKG_MGR="apk" +else + PKG_MGR="apt" +fi + +# ❌ Bad: Comment obvious code +# Set the variable +var="value" + +# ❌ Bad: Outdated comments +# TODO: Fix this (written 2 years ago, not fixed) +``` + +### File Organization + +```bash +#!/usr/bin/env bash # [1] Shebang (first line) +# Copyright & Metadata # [2] Comments + # [3] Blank line +# Load functions # [4] Import section +source <(curl -fsSL ...) + # [5] Blank line +# Configuration # [6] Variables/Config +APP="MyApp" +var_cpu="2" + # [7] Blank line +# Initialization # [8] Setup +header_info "$APP" +variables +color +catch_errors + # [9] Blank line +# Functions # [10] Function definitions +function update_script() { } +function custom_setup() { } + # [11] Blank line +# Main execution # [12] Script logic +start +build_container +``` + +--- + +## Testing Your Changes + +### Pre-Submission Testing + +#### 1. Syntax Check + +```bash +# Verify bash syntax +bash -n ct/myapp.sh +bash -n install/myapp-install.sh + +# If no output: βœ… Syntax is valid +# If error output: ❌ Fix syntax before submitting +``` + +#### 2. ShellCheck Static Analysis + +```bash +# Install ShellCheck +apt-get install -y shellcheck + +# Check scripts +shellcheck ct/myapp.sh +shellcheck install/myapp-install.sh + +# Review warnings and fix if applicable +# Some warnings can be intentional (use # shellcheck disable=...) +``` + +#### 3. Real Proxmox Testing + +```bash +# Best: Test on actual Proxmox system + +# 1. SSH into Proxmox host +ssh root@YOUR_PROXMOX_IP + +# 2. Download your script +curl -O https://raw.githubusercontent.com/YOUR_USER/ProxmoxVE/feat/myapp/ct/myapp.sh + +# 3. Make executable +chmod +x myapp.sh + +# 4. UPDATE URLS IN SCRIPT to point to your fork +sed -i 's|community-scripts|YOUR_USER|g' myapp.sh + +# 5. Run script +bash myapp.sh + +# 6. Test interaction: +# - Select installation mode +# - Confirm settings +# - Monitor installation + +# 7. Verify container created +pct list | grep myapp + +# 8. Log into container and verify app +pct exec 100 bash +``` + +#### 4. Edge Case Testing + +```bash +# Test with different settings: + +# Test 1: Advanced (19-step) installation +# When prompted: Select "2" for Advanced + +# Test 2: User Defaults +# Before running: Create ~/.community-scripts/default.vars +# When prompted: Select "3" for User Defaults + +# Test 3: Error handling +# Simulate network outage (block internet) +# Verify script handles gracefully + +# Test 4: Update function +# Create initial container +# Wait for new release +# Run update: bash ct/myapp.sh +# Verify it detects and applies update +``` + +### Testing Checklist + +Before submitting PR: + +```bash +# Code quality +- [ ] Syntax: bash -n passes +- [ ] ShellCheck: No critical warnings +- [ ] Naming: Follows conventions +- [ ] Formatting: Consistent indentation + +# Functionality +- [ ] Container creation: Successful +- [ ] Installation: Completes without errors +- [ ] Access URL: Works and app responds +- [ ] Update function: Detects new versions +- [ ] Cleanup: No temporary files left + +# Documentation +- [ ] Copyright header present +- [ ] App name matches filenames +- [ ] Default values realistic +- [ ] Success message clear and helpful + +# Compatibility +- [ ] Works on Debian 12 +- [ ] Works on Ubuntu 22.04 +- [ ] (Optional) Works on Alpine 3.20 +``` + +--- + +## Submitting a Pull Request + +### Step 1: Prepare Your Branch + +```bash +# Update with latest changes +git fetch upstream +git rebase upstream/main + +# If conflicts occur: +git rebase --abort +# Resolve conflicts manually then: +git add . +git rebase --continue +``` + +### Step 2: Push Your Changes + +```bash +git push origin feat/add-myapp + +# If already pushed: +git push origin feat/add-myapp --force-with-lease +``` + +### Step 3: Create Pull Request on GitHub + +**Visit**: https://github.com/community-scripts/ProxmoxVE/pulls + +**Click**: "New Pull Request" + +**Select**: `community-scripts:main` ← `YOUR_USERNAME:feat/myapp` + +### Step 4: Fill PR Description + +Use this template: + +```markdown +## Description +Brief description of what this PR adds/fixes + +## Type of Change +- [ ] New application (ct/AppName.sh + install/appname-install.sh) +- [ ] Update existing application +- [ ] Bug fix +- [ ] Documentation update +- [ ] Other: _______ + +## Testing +- [ ] Tested on Proxmox VE 8.x +- [ ] Container creation successful +- [ ] Application installation successful +- [ ] Application is accessible at URL +- [ ] Update function works (if applicable) +- [ ] No temporary files left after installation + +## Application Details (for new apps only) +- **App Name**: MyApp +- **Source**: https://github.com/app/repo +- **Default OS**: Debian 12 +- **Recommended Resources**: 2 CPU, 2GB RAM, 10GB Disk +- **Tags**: category;tag2;tag3 +- **Access URL**: http://IP:PORT/path + +## Checklist +- [ ] My code follows the style guidelines +- [ ] I have performed a self-review +- [ ] I have tested the script locally +- [ ] ShellCheck shows no critical warnings +- [ ] Documentation is accurate and complete +- [ ] I have added/updated relevant documentation +``` + +### Step 5: Respond to Review Comments + +**Maintainers may request changes**: +- Fix syntax/style issues +- Add better error handling +- Optimize resource usage +- Update documentation + +**To address feedback**: + +```bash +# Make requested changes +git add . +git commit -m "Address review feedback: ..." +git push origin feat/add-myapp + +# PR automatically updates! +# No need to create new PR +``` + +### Step 6: Celebrate! πŸŽ‰ + +Once merged, your contribution will be part of ProxmoxVE and available to all users! + +--- + +## Troubleshooting + +### "Repository not found" when cloning + +```bash +# Check your fork exists +# Visit: https://github.com/YOUR_USERNAME/ProxmoxVE + +# If not there: Click "Fork" on original repo first +``` + +### "Permission denied" when pushing + +```bash +# Setup SSH key +ssh-keygen -t ed25519 -C "your_email@example.com" +cat ~/.ssh/id_ed25519.pub # Copy this + +# Add to GitHub: Settings β†’ SSH Keys β†’ New Key + +# Or use HTTPS with token: +git remote set-url origin https://YOUR_TOKEN@github.com/YOUR_USERNAME/ProxmoxVE.git +``` + +### Script syntax errors + +```bash +# Use ShellCheck to identify issues +shellcheck install/myapp-install.sh + +# Common issues: +# - Unmatched quotes: "string' or 'string" +# - Missing semicolons before then: if [...]; then +# - Wrong quoting: echo $VAR instead of echo "${VAR}" +``` + +### Container creation fails immediately + +```bash +# 1. Check Proxmox resources +free -h # Check RAM +df -h # Check disk space +pct list # Check CTID availability + +# 2. Check script URL +# Make sure curl -s in script points to your fork + +# 3. Review errors +# Run with verbose: bash -x ct/myapp.sh +``` + +### App not accessible after creation + +```bash +# 1. Verify container running +pct list +pct status CTID + +# 2. Check if service running inside +pct exec CTID systemctl status myapp + +# 3. Check firewall +# Proxmox host: iptables -L +# Container: iptables -L + +# 4. Verify listening port +pct exec CTID netstat -tlnp | grep LISTEN +``` + +--- + +## FAQ + +### Q: Do I need to be a Bash expert? + +**A**: No! The codebase has many examples you can copy. Most contributions are straightforward script creation following the established patterns. + +### Q: Can I add a new application that's not open source? + +**A**: No. ProxmoxVE focuses on open-source applications (GPL, MIT, Apache, etc.). Closed-source applications won't be accepted. + +### Q: How long until my PR is reviewed? + +**A**: Maintainers are volunteers. Reviews typically happen within 1-2 weeks. Complex changes may take longer. + +### Q: Can I test without a Proxmox system? + +**A**: Partially. You can verify syntax and ShellCheck compliance locally, but real container testing requires Proxmox. Consider using: +- Proxmox in a VM (VirtualBox/KVM) +- Test instances on Hetzner/DigitalOcean +- Ask maintainers to test for you + +### Q: My update function is very complex - is that OK? + +**A**: Yes! Update functions can be complex if needed. Just ensure: +- Backup user data before updating +- Restore user data after update +- Test thoroughly before submitting +- Add clear comments explaining logic + +### Q: Can I add new dependencies to build.func? + +**A**: Generally no. build.func is the orchestrator and should remain stable. New functions should go in: +- `tools.func` - Tool installation +- `core.func` - Utility functions +- `install.func` - Container setup + +Ask in an issue first if you're unsure. + +### Q: What if the application has many configuration options? + +**A**: You have options: + +**Option 1**: Use Advanced mode (19-step wizard) +```bash +# Extend advanced_settings() if app needs special vars +``` + +**Option 2**: Create custom setup menu +```bash +function custom_config() { + OPTION=$(whiptail --inputbox "Enter database name:" 8 60) + # ... use $OPTION in installation +} +``` + +**Option 3**: Leave as defaults + documentation +```bash +# In success message: +echo "Edit /opt/myapp/config.json to customize settings" +``` + +### Q: Can I contribute Windows/macOS/ARM support? + +**A**: +- **Windows**: Not planned (ProxmoxVE is Linux/Proxmox focused) +- **macOS**: Can contribute Docker-based alternatives +- **ARM**: Yes! Many apps work on ARM. Add to vm/pimox-*.sh scripts + +--- + +## Getting Help + +### Resources + +- **Documentation**: `/docs` directory and wikis +- **Function Reference**: `/misc/*.md` wiki files +- **Examples**: Look at similar applications in `/ct` and `/install` +- **GitHub Issues**: https://github.com/community-scripts/ProxmoxVE/issues +- **Discussions**: https://github.com/community-scripts/ProxmoxVE/discussions + +### Ask Questions + +1. **Check existing issues** - Your question may be answered +2. **Search documentation** - See `/docs` and `/misc/*.md` +3. **Ask in Discussions** - For general questions +4. **Open an Issue** - For bugs or specific problems + +### Report Bugs + +When reporting bugs, include: +- Which application +- What happened (error message) +- What you expected +- Your Proxmox version +- Container OS and version + +Example: +``` +Title: pihole-install.sh fails on Alpine 3.20 + +Description: +Installation fails with error: "PHP-FPM not found" + +Expected: +PiHole should install successfully + +Environment: +- Proxmox VE 8.2 +- Alpine 3.20 +- Container CTID 110 + +Error Output: +[ERROR] in line 42: exit code 127: while executing command php-fpm --start +``` + +--- + +## Contribution Statistics + +**ProxmoxVE by the Numbers**: +- 🎯 40+ applications supported +- πŸ‘₯ 100+ contributors +- πŸ“Š 10,000+ GitHub stars +- πŸš€ 50+ releases +- πŸ“ˆ 100,000+ downloads/month + +**Your contribution makes a difference!** + +--- + +## Code of Conduct + +By contributing, you agree to: +- βœ… Be respectful and inclusive +- βœ… Follow the style guidelines +- βœ… Test your changes thoroughly +- βœ… Provide clear commit messages +- βœ… Respond to review feedback + +--- + +**Ready to contribute?** Start with the [Quick Start](#quick-start) section! + +**Questions?** Open an issue or start a discussion on GitHub. + +**Thank you for your contribution!** πŸ™ diff --git a/docs/contribution/README.md b/docs/contribution/README.md new file mode 100644 index 000000000..7737b6418 --- /dev/null +++ b/docs/contribution/README.md @@ -0,0 +1,341 @@ +# 🀝 Contributing to ProxmoxVE + +Complete guide to contributing to the ProxmoxVE project - from your first fork to submitting your pull request. + +--- + +## πŸ“‹ Table of Contents + +- [Quick Start](#quick-start) +- [Setting Up Your Fork](#setting-up-your-fork) +- [Coding Standards](#coding-standards) +- [Code Audit](#code-audit) +- [Guides & Resources](#guides--resources) +- [FAQ](#faq) + +--- + +## πŸš€ Quick Start + +### 60 Seconds to Contributing + +```bash +# 1. Fork on GitHub +# Visit: https://github.com/community-scripts/ProxmoxVE β†’ Fork (top right) + +# 2. Clone your fork +git clone https://github.com/YOUR_USERNAME/ProxmoxVE.git +cd ProxmoxVE + +# 3. Auto-configure your fork +bash docs/contribution/setup-fork.sh + +# 4. Create a feature branch +git checkout -b feature/my-awesome-app + +# 5. Read the guides +cat docs/README.md # Documentation overview +cat docs/ct/DETAILED_GUIDE.md # For container scripts +cat docs/install/DETAILED_GUIDE.md # For install scripts + +# 6. Create your contribution +cp ct/example.sh ct/myapp.sh +cp install/example-install.sh install/myapp-install.sh +# ... edit files ... + +# 7. Test and commit +bash ct/myapp.sh +git add ct/myapp.sh install/myapp-install.sh +git commit -m "feat: add MyApp" +git push origin feature/my-awesome-app + +# 8. Create Pull Request on GitHub +``` + +--- + +## 🍴 Setting Up Your Fork + +### Automatic Setup (Recommended) + +When you clone your fork, run the setup script to automatically configure everything: + +```bash +bash docs/contribution/setup-fork.sh +``` + +This will: +- Auto-detect your GitHub username +- Update all documentation links to point to your fork +- Create `.git-setup-info` with recommended git workflows + +**See**: [FORK_SETUP.md](FORK_SETUP.md) for detailed instructions + +### Manual Setup + +If the script doesn't work, manually configure: + +```bash +# Set git user +git config user.name "Your Name" +git config user.email "your.email@example.com" + +# Add upstream remote for syncing +git remote add upstream https://github.com/community-scripts/ProxmoxVE.git + +# Verify remotes +git remote -v +``` + +--- + +## πŸ“– Coding Standards + +All scripts and configurations must follow our coding standards to ensure consistency and quality. + +### Available Guides + +- **[CONTRIBUTING.md](CONTRIBUTING.md)** - Essential coding standards and best practices +- **[CODE_AUDIT.md](CODE_AUDIT.md)** - Code review checklist and audit procedures +- **Container Scripts** - `/ct/` templates and guidelines +- **Install Scripts** - `/install/` templates and guidelines +- **JSON Configurations** - `/json/` structure and format + +### Quick Checklist + +- βœ… Use `/ct/example.sh` as template for container scripts +- βœ… Use `/install/example-install.sh` as template for install scripts +- βœ… Follow naming conventions: `appname.sh` and `appname-install.sh` +- βœ… Include proper shebang: `#!/usr/bin/env bash` +- βœ… Add copyright header with author +- βœ… Handle errors properly with `msg_error`, `msg_ok`, etc. +- βœ… Test before submitting PR +- βœ… Update documentation if needed + +--- + +## πŸ” Code Audit + +Before submitting a pull request, ensure your code passes our audit: + +**See**: [CODE_AUDIT.md](CODE_AUDIT.md) for complete audit checklist + +Key points: +- Code consistency with existing scripts +- Proper error handling +- Correct variable naming +- Adequate comments and documentation +- Security best practices + +--- + +## πŸ“š Guides & Resources + +### Documentation + +- **[docs/README.md](../README.md)** - Main documentation hub +- **[docs/ct/README.md](../ct/README.md)** - Container scripts overview +- **[docs/install/README.md](../install/README.md)** - Installation scripts overview +- **[docs/ct/DETAILED_GUIDE.md](../ct/DETAILED_GUIDE.md)** - Complete ct/ script reference +- **[docs/install/DETAILED_GUIDE.md](../install/DETAILED_GUIDE.md)** - Complete install/ script reference +- **[docs/TECHNICAL_REFERENCE.md](../TECHNICAL_REFERENCE.md)** - Architecture deep-dive +- **[docs/EXIT_CODES.md](../EXIT_CODES.md)** - Exit codes reference +- **[docs/DEV_MODE.md](../DEV_MODE.md)** - Debugging guide + +### Community Guides + +See [USER_SUBMITTED_GUIDES.md](USER_SUBMITTED_GUIDES.md) for excellent community-written guides: +- Home Assistant installation and configuration +- Frigate setup on Proxmox +- Docker and Portainer installation +- Database setup and optimization +- And many more! + +### Templates + +Use these templates when creating new scripts: + +```bash +# Container script +cp ct/example.sh ct/my-app.sh + +# Installation script +cp install/example-install.sh install/my-app-install.sh + +# JSON configuration (if needed) +cp json/example.json json/my-app.json +``` + +--- + +## πŸ”„ Git Workflow + +### Keep Your Fork Updated + +```bash +# Fetch latest from upstream +git fetch upstream + +# Rebase your work on latest main +git rebase upstream/main + +# Push to your fork +git push -f origin main +``` + +### Create Feature Branch + +```bash +# Create and switch to new branch +git checkout -b feature/my-feature + +# Make changes... +git add . +git commit -m "feat: description of changes" + +# Push to your fork +git push origin feature/my-feature + +# Create Pull Request on GitHub +``` + +### Before Submitting PR + +1. **Sync with upstream** + ```bash + git fetch upstream + git rebase upstream/main + ``` + +2. **Test your changes** + ```bash + bash ct/my-app.sh + # Follow prompts and test the container + ``` + +3. **Check code standards** + - [ ] Follows template structure + - [ ] Proper error handling + - [ ] Documentation updated (if needed) + - [ ] No hardcoded values + - [ ] Version tracking implemented + +4. **Push final changes** + ```bash + git push origin feature/my-feature + ``` + +--- + +## πŸ“‹ Pull Request Checklist + +Before opening a PR: + +- [ ] Code follows coding standards (see CONTRIBUTING.md) +- [ ] All templates used correctly +- [ ] Tested on Proxmox VE +- [ ] Error handling implemented +- [ ] Documentation updated (if applicable) +- [ ] No merge conflicts +- [ ] Synced with upstream/main +- [ ] Clear PR title and description + +--- + +## ❓ FAQ + +### How do I test my changes? + +```bash +# For container scripts +bash ct/my-app.sh + +# For install scripts (runs inside container) +# The ct script will call it automatically + +# For advanced debugging +VERBOSE=yes bash ct/my-app.sh +``` + +### What if my PR has conflicts? + +```bash +# Sync with upstream +git fetch upstream +git rebase upstream/main + +# Resolve conflicts in your editor +git add . +git rebase --continue +git push -f origin your-branch +``` + +### How do I keep my fork updated? + +See "Keep Your Fork Updated" section above, or run: + +```bash +bash docs/contribution/setup-fork.sh +``` + +### Where do I ask questions? + +- **GitHub Issues**: For bugs and feature requests +- **GitHub Discussions**: For general questions +- **Discord**: Community-scripts server + +--- + +## πŸŽ“ Learning Resources + +### For First-Time Contributors + +1. Read: [docs/README.md](../README.md) - Documentation overview +2. Read: [docs/contribution/FORK_SETUP.md](FORK_SETUP.md) - Fork setup guide +3. Choose your path: + - Containers β†’ [docs/ct/DETAILED_GUIDE.md](../ct/DETAILED_GUIDE.md) + - Installation β†’ [docs/install/DETAILED_GUIDE.md](../install/DETAILED_GUIDE.md) +4. Study existing scripts in same category +5. Create your contribution + +### For Experienced Developers + +1. Review [CONTRIBUTING.md](CONTRIBUTING.md) - Coding standards +2. Review [CODE_AUDIT.md](CODE_AUDIT.md) - Audit checklist +3. Check templates in `/ct/` and `/install/` +4. Submit PR with confidence + +### For Reviewers/Maintainers + +1. Use [CODE_AUDIT.md](CODE_AUDIT.md) as review guide +2. Reference [docs/TECHNICAL_REFERENCE.md](../TECHNICAL_REFERENCE.md) for architecture +3. Check [docs/EXIT_CODES.md](../EXIT_CODES.md) for error handling + +--- + +## πŸš€ Ready to Contribute? + +1. **Fork** the repository +2. **Clone** your fork and **setup** with `bash docs/contribution/setup-fork.sh` +3. **Choose** your contribution type (container, installation, tools, etc.) +4. **Read** the appropriate detailed guide +5. **Create** your feature branch +6. **Develop** and **test** your changes +7. **Commit** with clear messages +8. **Push** to your fork +9. **Create** Pull Request + +--- + +## πŸ“ž Contact & Support + +- **GitHub**: https://github.com/community-scripts/ProxmoxVE +- **Issues**: https://github.com/community-scripts/ProxmoxVE/issues +- **Discussions**: https://github.com/community-scripts/ProxmoxVE/discussions +- **Discord**: [Join Server](https://discord.gg/UHrpNWGwkH) + +--- + +**Thank you for contributing to ProxmoxVE!** πŸ™ + +Your efforts help make Proxmox VE automation accessible to everyone. Happy coding! πŸš€ diff --git a/docs/contribution/USER_SUBMITTED_GUIDES.md b/docs/contribution/USER_SUBMITTED_GUIDES.md new file mode 100644 index 000000000..795993950 --- /dev/null +++ b/docs/contribution/USER_SUBMITTED_GUIDES.md @@ -0,0 +1,44 @@ + +

User Submitted Guides

+ + In order to contribute a guide on installing with Proxmox VE Helper Scripts, you should open a pull request that adds the guide to the `USER_SUBMITTED_GUIDES.md` file. + +[Proxmox Automation with Proxmox Helper Scripts!](https://www.youtube.com/watch?v=kcpu4z5eSEU) + +[Installing Home Assistant OS using Proxmox 8](https://community.home-assistant.io/t/installing-home-assistant-os-using-proxmox-8/201835) + +[How To Separate Zigbee2MQTT From Home Assistant In Proxmox](https://smarthomescene.com/guides/how-to-separate-zigbee2mqtt-from-home-assistant-in-proxmox/) + +[How To Install Home Assistant On Proxmox: The Easy Way](https://smarthomescene.com/guides/how-to-install-home-assistant-on-proxmox-the-easy-way/) + +[Home Assistant: Installing InfluxDB (LXC)](https://www.derekseaman.com/2023/04/home-assistant-installing-influxdb-lxc.html) + +[Home Assistant: Proxmox Quick Start Guide](https://www.derekseaman.com/2023/10/home-assistant-proxmox-ve-8-0-quick-start-guide-2.html) + +[Home Assistant: Installing Grafana (LXC) with Let’s Encrypt SSL](https://www.derekseaman.com/2023/04/home-assistant-installing-grafana-lxc.html) + +[Proxmox: Plex LXC with Alder Lake Transcoding](https://www.derekseaman.com/2023/04/proxmox-plex-lxc-with-alder-lake-transcoding.html) + +[How To Backup Home Assistant In Proxmox](https://smarthomescene.com/guides/how-to-backup-home-assistant-in-proxmox/) + +[Running Frigate on Proxmox](https://www.homeautomationguy.io/blog/running-frigate-on-proxmox) + +[Frigate VM on Proxmox with PCIe Coral TPU](https://www.derekseaman.com/2023/06/home-assistant-frigate-vm-on-proxmox-with-pcie-coral-tpu.html) + +[Moving Home Assistant’s Database To MariaDB On Proxmox](https://smarthomescene.com/guides/moving-home-assistants-database-to-mariadb-on-proxmox/) + +[How-to: Proxmox VE 7.4 to 8.0 Upgrade](https://www.derekseaman.com/2023/06/how-to-proxmox-7-4-to-8-0-upgrade.html) + +[iGPU Transcoding In Proxmox with Jellyfin](https://www.youtube.com/watch?v=XAa_qpNmzZs) + +[Proxmox + NetData]() + +[Proxmox Homelab Series]() + +[The fastest installation of Docker and Portainer on Proxmox VE](https://lavr.site/en-fastest-install-docker-portainer-proxmox/) + +[How To Setup Proxmox Backuper Server Using Helper Scripts]() diff --git a/docs/contribution/setup-fork.sh b/docs/contribution/setup-fork.sh new file mode 100644 index 000000000..f140babb9 --- /dev/null +++ b/docs/contribution/setup-fork.sh @@ -0,0 +1,313 @@ +#!/bin/bash + +################################################################################ +# ProxmoxVE Fork Setup Script +# +# Automatically configures documentation and scripts for your fork +# Detects your GitHub username and repository from git config +# Updates all hardcoded links to point to your fork +# +# Usage: +# ./setup-fork.sh # Auto-detect from git config +# ./setup-fork.sh YOUR_USERNAME # Specify username +# ./setup-fork.sh YOUR_USERNAME REPO_NAME # Specify both +# +# Examples: +# ./setup-fork.sh john # Uses john/ProxmoxVE +# ./setup-fork.sh john my-fork # Uses john/my-fork +################################################################################ + +set -e + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +# Default values +REPO_NAME="ProxmoxVE" +USERNAME="" +AUTO_DETECT=true + +################################################################################ +# FUNCTIONS +################################################################################ + +print_header() { + echo -e "\n${BLUE}╔════════════════════════════════════════════════════════════╗${NC}" + echo -e "${BLUE}β•‘${NC} ProxmoxVE Fork Setup Script" + echo -e "${BLUE}β•‘${NC} Configuring for your fork..." + echo -e "${BLUE}β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•${NC}\n" +} + +print_info() { + echo -e "${BLUE}β„Ή${NC} $1" +} + +print_success() { + echo -e "${GREEN}βœ“${NC} $1" +} + +print_warning() { + echo -e "${YELLOW}⚠${NC} $1" +} + +print_error() { + echo -e "${RED}βœ—${NC} $1" +} + +# Detect username from git remote +detect_username() { + local remote_url + + # Try to get from origin + if ! remote_url=$(git config --get remote.origin.url 2>/dev/null); then + return 1 + fi + + # Extract username from SSH or HTTPS URL + if [[ $remote_url =~ git@github.com:([^/]+) ]]; then + echo "${BASH_REMATCH[1]}" + elif [[ $remote_url =~ github.com/([^/]+) ]]; then + echo "${BASH_REMATCH[1]}" + else + return 1 + fi +} + +# Detect repo name from git remote +detect_repo_name() { + local remote_url + + if ! remote_url=$(git config --get remote.origin.url 2>/dev/null); then + return 1 + fi + + # Extract repo name (remove .git if present) + if [[ $remote_url =~ /([^/]+?)(.git)?$ ]]; then + local repo="${BASH_REMATCH[1]}" + echo "${repo%.git}" + else + return 1 + fi +} + +# Ask user for confirmation +confirm() { + local prompt="$1" + local response + + read -p "$(echo -e ${YELLOW})$prompt (y/n)${NC} " -r response + [[ $response =~ ^[Yy]$ ]] +} + +# Update links in files +update_links() { + local old_repo="community-scripts" + local old_name="ProxmoxVE" + local new_owner="$1" + local new_repo="$2" + local files_updated=0 + + print_info "Scanning for hardcoded links..." + + # Find all markdown and shell files + local -a files_to_update=( + "docs/DEFAULTS_SYSTEM_GUIDE.md" + "docs/alpine-install.func.md" + "docs/install.func.md" + "docs/APP-install.md" + "docs/APP-ct.md" + "docs/CONTRIBUTION_GUIDE.md" + "docs/INDEX.md" + "docs/README.md" + "docs/EXIT_CODES.md" + "docs/api/README.md" + ) + + echo "" + + for file in "${files_to_update[@]}"; do + if [[ -f "$file" ]]; then + # Count occurrences + local count=$(grep -c "github.com/$old_repo/$old_name" "$file" 2>/dev/null || echo 0) + + if [[ $count -gt 0 ]]; then + # Backup original + cp "$file" "$file.backup" + + # Replace links + sed -i "s|github.com/$old_repo/$old_name|github.com/$new_owner/$new_repo|g" "$file" + + ((files_updated++)) + print_success "Updated $file ($count links)" + fi + fi + done + + return $files_updated +} + +# Create user git config setup info +create_git_setup_info() { + local username="$1" + + cat >.git-setup-info <<'EOF' +# Git Configuration for ProxmoxVE Development + +## Recommended Git Configuration + +### Set up remotes for easy syncing with upstream: + +```bash +# View your current remotes +git remote -v + +# If you don't have 'upstream' configured, add it: +git remote add upstream https://github.com/community-scripts/ProxmoxVE.git + +# Verify both remotes exist: +git remote -v +# Should show: +# origin https://github.com/YOUR_USERNAME/ProxmoxVE.git (fetch) +# origin https://github.com/YOUR_USERNAME/ProxmoxVE.git (push) +# upstream https://github.com/community-scripts/ProxmoxVE.git (fetch) +# upstream https://github.com/community-scripts/ProxmoxVE.git (push) +``` + +### Configure Git User (if not done globally) + +```bash +git config user.name "Your Name" +git config user.email "your.email@example.com" + +# Or configure globally: +git config --global user.name "Your Name" +git config --global user.email "your.email@example.com" +``` + +### Useful Git Workflows + +**Keep your fork up-to-date:** +```bash +git fetch upstream +git rebase upstream/main +git push origin main +``` + +**Create feature branch:** +```bash +git checkout -b feature/my-awesome-app +# Make changes... +git commit -m "feat: add my awesome app" +git push origin feature/my-awesome-app +``` + +**Pull latest from upstream:** +```bash +git fetch upstream +git merge upstream/main +``` + +--- + +For more help, see: docs/CONTRIBUTION_GUIDE.md +EOF + + print_success "Created .git-setup-info file" +} + +################################################################################ +# MAIN LOGIC +################################################################################ + +print_header + +# Parse command line arguments +if [[ $# -gt 0 ]]; then + USERNAME="$1" + AUTO_DETECT=false + + if [[ $# -gt 1 ]]; then + REPO_NAME="$2" + fi +else + # Try auto-detection + if username=$(detect_username); then + USERNAME="$username" + print_success "Detected GitHub username: $USERNAME" + else + print_error "Could not auto-detect GitHub username from git config" + echo -e "${YELLOW}Please run:${NC}" + echo " ./setup-fork.sh YOUR_USERNAME" + exit 1 + fi + + if repo_name=$(detect_repo_name); then + REPO_NAME="$repo_name" + if [[ "$REPO_NAME" != "ProxmoxVE" ]]; then + print_info "Detected custom repo name: $REPO_NAME" + else + print_success "Using default repo name: ProxmoxVE" + fi + fi +fi + +# Validate inputs +if [[ -z "$USERNAME" ]]; then + print_error "Username cannot be empty" + exit 1 +fi + +if [[ -z "$REPO_NAME" ]]; then + print_error "Repository name cannot be empty" + exit 1 +fi + +# Show what we'll do +echo -e "${BLUE}Configuration Summary:${NC}" +echo " Repository URL: https://github.com/$USERNAME/$REPO_NAME" +echo " Files to update: 10 files with documentation" +echo "" + +# Ask for confirmation +if ! confirm "Apply these changes?"; then + print_warning "Setup cancelled" + exit 0 +fi + +echo "" + +# Update all links +if update_links "$USERNAME" "$REPO_NAME"; then + links_changed=$? + print_success "Updated $links_changed files" +else + print_warning "No links needed updating or some files not found" +fi + +# Create git setup info file +create_git_setup_info "$USERNAME" + +# Final summary +echo "" +echo -e "${GREEN}╔════════════════════════════════════════════════════════════╗${NC}" +echo -e "${GREEN}β•‘${NC} Fork Setup Complete! ${GREEN}β•‘${NC}" +echo -e "${GREEN}β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•${NC}" +echo "" + +print_success "All documentation links updated to point to your fork" +print_info "Your fork: https://github.com/$USERNAME/$REPO_NAME" +print_info "Upstream: https://github.com/community-scripts/ProxmoxVE" +echo "" + +echo -e "${BLUE}Next Steps:${NC}" +echo " 1. Review the changes: git diff" +echo " 2. Check .git-setup-info for recommended git workflow" +echo " 3. Start developing: git checkout -b feature/my-app" +echo " 4. Read: docs/CONTRIBUTION_GUIDE.md" +echo "" + +print_success "Happy contributing! πŸš€" diff --git a/docs/contribution/templates_ct/AppName.md b/docs/contribution/templates_ct/AppName.md new file mode 100644 index 000000000..6698ecc0b --- /dev/null +++ b/docs/contribution/templates_ct/AppName.md @@ -0,0 +1,286 @@ +# **AppName.sh Scripts** + + `AppName.sh` scripts found in the `/ct` directory. These scripts are responsible for the installation of the desired application. For this guide we take `/ct/snipeit.sh` as example. + +## Table of Contents + +- [**AppName.sh Scripts**](#appnamesh-scripts) + - [Table of Contents](#table-of-contents) + - [1. **File Header**](#1-file-header) + - [1.1 **Shebang**](#11-shebang) + - [1.2 **Import Functions**](#12-import-functions) + - [1.3 **Metadata**](#13-metadata) + - [2 **Variables and function import**](#2-variables-and-function-import) + - [2.1 **Default Values**](#21-default-values) + - [2.2 **πŸ“‹ App output \& base settings**](#22--app-output--base-settings) + - [2.3 **πŸ›  Core functions**](#23--core-functions) + - [3 **Update function**](#3-update-function) + - [3.1 **Function Header**](#31-function-header) + - [3.2 **Check APP**](#32-check-app) + - [3.3 **Check version**](#33-check-version) + - [3.4 **Verbosity**](#34-verbosity) + - [3.5 **Backups**](#35-backups) + - [3.6 **Cleanup**](#36-cleanup) + - [3.7 **No update function**](#37-no-update-function) + - [4 **End of the script**](#4-end-of-the-script) + - [5. **Contribution checklist**](#5-contribution-checklist) + +## 1. **File Header** + +### 1.1 **Shebang** + +- Use `#!/usr/bin/env bash` as the shebang. + +```bash +#!/usr/bin/env bash +``` + +### 1.2 **Import Functions** + +- Import the build.func file. +- When developing your own script, change the URL to your own repository. + +> [!IMPORTANT] +> You also need to change all apperances of this URL in `misc/build.func` and `misc/install.func` + +Example for development: + +```bash +source <(curl -s https://raw.githubusercontent.com/[USER]/[REPO]/refs/heads/[BRANCH]/misc/build.func) +``` + +Final script: + +```bash +source <(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func) +``` + +> [!CAUTION] +> Before opening a Pull Request, change the URLs to point to the community-scripts repo. + +### 1.3 **Metadata** + +- Add clear comments for script metadata, including author, copyright, and license information. + +Example: + +```bash +# Copyright (c) 2021-2025 community-scripts ORG +# Author: [YourUserName] +# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE +# Source: [SOURCE_URL] +``` + +> [!NOTE]: +> +> - Add your username and source URL +> - For existing scripts, add "| Co-Author [YourUserName]" after the current author + +--- + +## 2 **Variables and function import** +> +> [!NOTE] +> You need to have all this set in your script, otherwise it will not work! + +### 2.1 **Default Values** + +- This section sets the default values for the container. +- `APP` needs to be set to the application name and must be equal to the filenames of your scripts. +- `var_tags`: You can set Tags for the CT wich show up in the Proxmox UI. DonΒ΄t overdo it! + +>[!NOTE] +>Description for all Default Values +> +>| Variable | Description | Notes | +>|----------|-------------|-------| +>| `APP` | Application name | Must match ct\AppName.sh | +>| `var_tags` | Proxmox display tags without Spaces, only ; | Limit the number | +>| `var_cpu` | CPU cores | Number of cores | +>| `var_ram` | RAM | In MB | +>| `var_disk` | Disk capacity | In GB | +>| `var_os` | Operating system | alpine, debian, ubuntu | +>| `var_version` | OS version | e.g., 3.20, 11, 12, 20.04 | +>| `var_unprivileged` | Container type | 1 = Unprivileged, 0 = Privileged | + +Example: + +```bash +APP="SnipeIT" +var_tags="asset-management;foss" +var_cpu="2" +var_ram="2048" +var_disk="4" +var_os="debian" +var_version="12" +var_unprivileged="1" +``` + +## 2.2 **πŸ“‹ App output & base settings** + +```bash +header_info "$APP" +``` +- `header_info`: Generates ASCII header for APP + +## 2.3 **πŸ›  Core functions** + +```bash +variables +color +catch_errors +``` + +- `variables`: Processes input and prepares variables +- `color`: Sets icons, colors, and formatting +- `catch_errors`: Enables error handling + +--- + +## 3 **Update function** + +### 3.1 **Function Header** + +- If applicable write a function that updates the application and the OS in the container. +- Each update function starts with the same code: + +```bash +function update_script() { + header_info + check_container_storage + check_container_resources +``` + +### 3.2 **Check APP** + +- Before doing anything update-wise, check if the app is installed in the container. + +Example: + +```bash +if [[ ! -d /opt/snipe-it ]]; then + msg_error "No ${APP} Installation Found!" + exit + fi +``` + +### 3.3 **Check version** + +- Before updating, check if a new version exists. + - We use the `${APPLICATION}_version.txt` file created in `/opt` during the install to compare new versions against the currently installed version. + +Example with a Github Release: + +```bash + RELEASE=$(curl -fsSL https://api.github.com/repos/snipe/snipe-it/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') + if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then + msg_info "Updating ${APP} to v${RELEASE}" + #DO UPDATE + else + msg_ok "No update required. ${APP} is already at v${RELEASE}." + fi + exit +} +``` + +### 3.4 **Verbosity** + +- Use the appropriate flag (**-q** in the examples) for a command to suppress its output. +Example: + +```bash +curl -fsSL +unzip -q +``` + +- If a command does not come with this functionality use `$STD` to suppress it's output. + +Example: + +```bash +$STD php artisan migrate --force +$STD php artisan config:clear +``` + +### 3.5 **Backups** + +- Backup user data if necessary. +- Move all user data back in the directory when the update is finished. + +>[!NOTE] +>This is not meant to be a permanent backup + +Example backup: + +```bash + mv /opt/snipe-it /opt/snipe-it-backup +``` + +Example config restore: + +```bash + cp /opt/snipe-it-backup/.env /opt/snipe-it/.env + cp -r /opt/snipe-it-backup/public/uploads/ /opt/snipe-it/public/uploads/ + cp -r /opt/snipe-it-backup/storage/private_uploads /opt/snipe-it/storage/private_uploads +``` + +### 3.6 **Cleanup** + +- Do not forget to remove any temporary files/folders such as zip-files or temporary backups. +Example: + +```bash + rm -rf /opt/v${RELEASE}.zip + rm -rf /opt/snipe-it-backup +``` + +### 3.7 **No update function** + +- In case you can not provide an update function use the following code to provide user feedback. + +```bash +function update_script() { + header_info + check_container_storage + check_container_resources + if [[ ! -d /opt/snipeit ]]; then + msg_error "No ${APP} Installation Found!" + exit + fi + msg_error "Currently we don't provide an update function for this ${APP}." + exit +} +``` + +--- + +## 4 **End of the script** + +- `start`: Launches Whiptail dialogue +- `build_container`: Collects and integrates user settings +- `description`: Sets LXC container description +- With `echo -e "${TAB}${GATEWAY}${BGN}http://${IP}${CL}"` you can point the user to the IP:PORT/folder needed to access the app. + +```bash +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}" +echo -e "${INFO}${YW} Access it using the following URL:${CL}" +echo -e "${TAB}${GATEWAY}${BGN}http://${IP}${CL}" +``` + +--- + +## 5. **Contribution checklist** + +- [ ] Shebang is correctly set (`#!/usr/bin/env bash`). +- [ ] Correct link to *build.func* +- [ ] Metadata (author, license) is included at the top. +- [ ] Variables follow naming conventions. +- [ ] Update function exists. +- [ ] Update functions checks if app is installed and for new version. +- [ ] Update function cleans up temporary files. +- [ ] Script ends with a helpful message for the user to reach the application. diff --git a/docs/contribution/templates_ct/AppName.sh b/docs/contribution/templates_ct/AppName.sh new file mode 100644 index 000000000..14c0244eb --- /dev/null +++ b/docs/contribution/templates_ct/AppName.sh @@ -0,0 +1,86 @@ +#!/usr/bin/env bash +source <(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func) +# Copyright (c) 2021-2025 community-scripts ORG +# Author: [YourUserName] +# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE +# Source: [SOURCE_URL] + +# App Default Values +APP="[APP_NAME]" +# Name of the app (e.g. Google, Adventurelog, Apache-Guacamole" +var_tags="[TAGS]" +# Tags for Proxmox VE, maximum 2 pcs., no spaces allowed, separated by a semicolon ; (e.g. database | adblock;dhcp) +var_cpu="[CPU]" +# Number of cores (1-X) (e.g. 4) - default are 2 +var_ram="[RAM]" +# Amount of used RAM in MB (e.g. 2048 or 4096) +var_disk="[DISK]" +# Amount of used disk space in GB (e.g. 4 or 10) +var_os="[OS]" +# Default OS (e.g. debian, ubuntu, alpine) +var_version="[VERSION]" +# Default OS version (e.g. 12 for debian, 24.04 for ubuntu, 3.20 for alpine) +var_unprivileged="[UNPRIVILEGED]" +# 1 = unprivileged container, 0 = privileged container + +header_info "$APP" +variables +color +catch_errors + +function update_script() { + header_info + check_container_storage + check_container_resources + + # Check if installation is present | -f for file, -d for folder + if [[ ! -f [INSTALLATION_CHECK_PATH] ]]; then + msg_error "No ${APP} Installation Found!" + exit + fi + + # Crawling the new version and checking whether an update is required + RELEASE=$(curl -fsSL [RELEASE_URL] | [PARSE_RELEASE_COMMAND]) + if [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]] || [[ ! -f /opt/${APP}_version.txt ]]; then + # Stopping Services + msg_info "Stopping $APP" + systemctl stop [SERVICE_NAME] + msg_ok "Stopped $APP" + + # Creating Backup + msg_info "Creating Backup" + tar -czf "/opt/${APP}_backup_$(date +%F).tar.gz" [IMPORTANT_PATHS] + msg_ok "Backup Created" + + # Execute Update + msg_info "Updating $APP to v${RELEASE}" + [UPDATE_COMMANDS] + msg_ok "Updated $APP to v${RELEASE}" + + # Starting Services + msg_info "Starting $APP" + systemctl start [SERVICE_NAME] + msg_ok "Started $APP" + + # Cleaning up + msg_info "Cleaning Up" + rm -rf [TEMP_FILES] + msg_ok "Cleanup Completed" + + # Last Action + echo "${RELEASE}" >/opt/${APP}_version.txt + msg_ok "Update Successful" + else + msg_ok "No update required. ${APP} is already at v${RELEASE}" + fi + exit +} + +start +build_container +description + +msg_ok "Completed Successfully!\n" +echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}" +echo -e "${INFO}${YW} Access it using the following URL:${CL}" +echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:[PORT]${CL}" diff --git a/docs/contribution/templates_install/AppName-install.md b/docs/contribution/templates_install/AppName-install.md new file mode 100644 index 000000000..f6a2c3fd5 --- /dev/null +++ b/docs/contribution/templates_install/AppName-install.md @@ -0,0 +1,353 @@ + +# **AppName-install.sh Scripts** + + `AppName-install.sh` scripts found in the `/install` directory. These scripts are responsible for the installation of the application. For this guide we take `/install/snipeit-install.sh` as example. + +## Table of Contents + +- [**AppName-install.sh Scripts**](#appname-installsh-scripts) + - [Table of Contents](#table-of-contents) + - [1. **File header**](#1-file-header) + - [1.1 **Shebang**](#11-shebang) + - [1.2 **Comments**](#12-comments) + - [1.3 **Variables and function import**](#13-variables-and-function-import) + - [2. **Variable naming and management**](#2-variable-naming-and-management) + - [2.1 **Naming conventions**](#21-naming-conventions) + - [3. **Dependencies**](#3-dependencies) + - [3.1 **Install all at once**](#31-install-all-at-once) + - [3.2 **Collapse dependencies**](#32-collapse-dependencies) + - [4. **Paths to application files**](#4-paths-to-application-files) + - [5. **Version management**](#5-version-management) + - [5.1 **Install the latest release**](#51-install-the-latest-release) + - [5.2 **Save the version for update checks**](#52-save-the-version-for-update-checks) + - [6. **Input and output management**](#6-input-and-output-management) + - [6.1 **User feedback**](#61-user-feedback) + - [6.2 **Verbosity**](#62-verbosity) + - [7. **String/File Manipulation**](#7-stringfile-manipulation) + - [7.1 **File Manipulation**](#71-file-manipulation) + - [8. **Security practices**](#8-security-practices) + - [8.1 **Password generation**](#81-password-generation) + - [8.2 **File permissions**](#82-file-permissions) + - [9. **Service Configuration**](#9-service-configuration) + - [9.1 **Configuration files**](#91-configuration-files) + - [9.2 **Credential management**](#92-credential-management) + - [9.3 **Enviroment files**](#93-enviroment-files) + - [9.4 **Services**](#94-services) + - [10. **Cleanup**](#10-cleanup) + - [10.1 **Remove temporary files**](#101-remove-temporary-files) + - [10.2 **Autoremove and autoclean**](#102-autoremove-and-autoclean) + - [11. **Best Practices Checklist**](#11-best-practices-checklist) + - [Example: High-Level Script Flow](#example-high-level-script-flow) + +## 1. **File header** + +### 1.1 **Shebang** + +- Use `#!/usr/bin/env bash` as the shebang. + +```bash +#!/usr/bin/env bash +``` + +### 1.2 **Comments** + +- Add clear comments for script metadata, including author, copyright, and license information. +- Use meaningful inline comments to explain complex commands or logic. + +Example: + +```bash +# Copyright (c) 2021-2025 community-scripts ORG +# Author: [YourUserName] +# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE +# Source: [SOURCE_URL] +``` + +> [!NOTE]: +> +> - Add your username +> - When updating/reworking scripts, add "| Co-Author [YourUserName]" + +### 1.3 **Variables and function import** + +- This sections adds the support for all needed functions and variables. + +```bash +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os +``` + +--- + +## 2. **Variable naming and management** + +### 2.1 **Naming conventions** + +- Use uppercase names for constants and environment variables. +- Use lowercase names for local script variables. + +Example: + +```bash +DB_NAME=snipeit_db # Environment-like variable (constant) +db_user="snipeit" # Local variable +``` + +--- + +## 3. **Dependencies** + +### 3.1 **Install all at once** + +- Install all dependencies with a single command if possible + +Example: + +```bash +$STD apt-get install -y \ + curl \ + composer \ + git \ + sudo \ + mc \ + nginx +``` + +### 3.2 **Collapse dependencies** + +Collapse dependencies to keep the code readable. + +Example: +Use + +```bash +php8.2-{bcmath,common,ctype} +``` + +instead of + +```bash +php8.2-bcmath php8.2-common php8.2-ctype +``` + +--- + +## 4. **Paths to application files** + +If possible install the app and all necessary files in `/opt/` + +--- + +## 5. **Version management** + +### 5.1 **Install the latest release** + +- Always try and install the latest release +- Do not hardcode any version if not absolutely necessary + +Example for a git release: + +```bash +RELEASE=$(curl -fsSL https://api.github.com/repos/snipe/snipe-it/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') +curl -fsSL "https://github.com/snipe/snipe-it/archive/refs/tags/v${RELEASE}.zip" +``` + +### 5.2 **Save the version for update checks** + +- Write the installed version into a file. +- This is used for the update function in **AppName.sh** to check for if a Update is needed. + +Example: + +```bash +echo "${RELEASE}" >"/opt/AppName_version.txt" +``` + +--- + +## 6. **Input and output management** + +### 6.1 **User feedback** + +- Use standard functions like `msg_info`, `msg_ok` or `msg_error` to print status messages. +- Each `msg_info` must be followed with a `msg_ok` before any other output is made. +- Display meaningful progress messages at key stages. + +Example: + +```bash +msg_info "Installing Dependencies" +$STD apt-get install -y ... +msg_ok "Installed Dependencies" +``` + +### 6.2 **Verbosity** + +- Use the appropiate flag (**-q** in the examples) for a command to suppres its output +Example: + +```bash +curl -fsSL +unzip -q +``` + +- If a command dose not come with such a functionality use `$STD` (a custom standard redirection variable) for managing output verbosity. + +Example: + +```bash +$STD apt-get install -y nginx +``` + +--- + +## 7. **String/File Manipulation** + +### 7.1 **File Manipulation** + +- Use `sed` to replace placeholder values in configuration files. + +Example: + +```bash +sed -i -e "s|^DB_DATABASE=.*|DB_DATABASE=$DB_NAME|" \ + -e "s|^DB_USERNAME=.*|DB_USERNAME=$DB_USER|" \ + -e "s|^DB_PASSWORD=.*|DB_PASSWORD=$DB_PASS|" .env +``` + +--- + +## 8. **Security practices** + +### 8.1 **Password generation** + +- Use `openssl` to generate random passwords. +- Use only alphanumeric values to not introduce unknown behaviour. + +Example: + +```bash +DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13) +``` + +### 8.2 **File permissions** + +Explicitly set secure ownership and permissions for sensitive files. + +Example: + +```bash +chown -R www-data: /opt/snipe-it +chmod -R 755 /opt/snipe-it +``` + +--- + +## 9. **Service Configuration** + +### 9.1 **Configuration files** + +Use `cat </etc/nginx/conf.d/snipeit.conf +server { + listen 80; + root /opt/snipe-it/public; + index index.php; +} +EOF +``` + +### 9.2 **Credential management** + +Store the generated credentials in a file. + +Example: + +```bash +USERNAME=username +PASSWORD=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13) +{ + echo "Application-Credentials" + echo "Username: $USERNAME" + echo "Password: $PASSWORD" +} >> ~/application.creds +``` + +### 9.3 **Enviroment files** + +Use `cat </path/to/.env +VARIABLE="value" +PORT=3000 +DB_NAME="${DB_NAME}" +EOF +``` + +### 9.4 **Services** + +Enable affected services after configuration changes and start them right away. + +Example: + +```bash +systemctl enable -q --now nginx +``` + +--- + +## 10. **Cleanup** + +### 10.1 **Remove temporary files** + +Remove temporary files and downloads after use. + +Example: + +```bash +rm -rf /opt/v${RELEASE}.zip +``` + +### 10.2 **Autoremove and autoclean** + +Remove unused dependencies to reduce disk space usage. + +Example: + +```bash +apt-get -y autoremove +apt-get -y autoclean +``` + +--- + +## 11. **Best Practices Checklist** + +- [ ] Shebang is correctly set (`#!/usr/bin/env bash`). +- [ ] Metadata (author, license) is included at the top. +- [ ] Variables follow naming conventions. +- [ ] Sensitive values are dynamically generated. +- [ ] Files and services have proper permissions. +- [ ] Script cleans up temporary files. + +--- + +### Example: High-Level Script Flow + +1. Dependencies installation +2. Database setup +3. Download and configure application +4. Service configuration +5. Final cleanup diff --git a/docs/contribution/templates_install/AppName-install.sh b/docs/contribution/templates_install/AppName-install.sh new file mode 100644 index 000000000..27e6b8f4e --- /dev/null +++ b/docs/contribution/templates_install/AppName-install.sh @@ -0,0 +1,83 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2025 community-scripts ORG +# Author: [YourUserName] +# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE +# Source: [SOURCE_URL] + +# Import Functions und Setup +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +# Installing Dependencies with the 3 core dependencies (curl;sudo;mc) +msg_info "Installing Dependencies" +$STD apt-get install -y \ + curl \ + sudo \ + mc \ + [PACKAGE_1] \ + [PACKAGE_2] \ + [PACKAGE_3] +msg_ok "Installed Dependencies" + +# Template: MySQL Database +msg_info "Setting up Database" +DB_NAME=[DB_NAME] +DB_USER=[DB_USER] +DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13) +$STD mysql -u root -e "CREATE DATABASE $DB_NAME;" +$STD mysql -u root -e "CREATE USER '$DB_USER'@'localhost' IDENTIFIED WITH mysql_native_password AS PASSWORD('$DB_PASS');" +$STD mysql -u root -e "GRANT ALL ON $DB_NAME.* TO '$DB_USER'@'localhost'; FLUSH PRIVILEGES;" +{ + echo "${APPLICATION} Credentials" + echo "Database User: $DB_USER" + echo "Database Password: $DB_PASS" + echo "Database Name: $DB_NAME" +} >>~/$APP_NAME.creds +msg_ok "Set up Database" + +# Temp + +# Setup App +msg_info "Setup ${APPLICATION}" +RELEASE=$(curl -s https://api.github.com/repos/[REPO]/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') +curl -fsSL "https://github.com/[REPO]/archive/refs/tags/${RELEASE}.zip" +unzip -q ${RELEASE}.zip +mv ${APPLICATION}-${RELEASE}/ /opt/${APPLICATION} +# +# +# +echo "${RELEASE}" >/opt/${APPLICATION}_version.txt +msg_ok "Setup ${APPLICATION}" + +# Creating Service (if needed) +msg_info "Creating Service" +cat </etc/systemd/system/${APPLICATION}.service +[Unit] +Description=${APPLICATION} Service +After=network.target + +[Service] +ExecStart=[START_COMMAND] +Restart=always + +[Install] +WantedBy=multi-user.target +EOF +systemctl enable -q --now ${APPLICATION}.service +msg_ok "Created Service" + +motd_ssh +customize + +# Cleanup +msg_info "Cleaning up" +rm -f ${RELEASE}.zip +$STD apt-get -y autoremove +$STD apt-get -y autoclean +msg_ok "Cleaned" diff --git a/docs/ct/DETAILED_GUIDE.md b/docs/ct/DETAILED_GUIDE.md new file mode 100644 index 000000000..3293c2e66 --- /dev/null +++ b/docs/ct/DETAILED_GUIDE.md @@ -0,0 +1,472 @@ +# πŸš€ **Application Container Scripts (ct/AppName.sh)** + +**Modern Guide to Creating LXC Container Installation Scripts** + +> **Updated**: December 2025 +> **Context**: Fully integrated with build.func, advanced_settings wizard, and defaults system +> **Example Used**: `/ct/pihole.sh`, `/ct/docker.sh` + +--- + +## πŸ“‹ Table of Contents + +- [Overview](#overview) +- [Architecture & Flow](#architecture--flow) +- [File Structure](#file-structure) +- [Complete Script Template](#complete-script-template) +- [Function Reference](#function-reference) +- [Advanced Features](#advanced-features) +- [Real Examples](#real-examples) +- [Troubleshooting](#troubleshooting) +- [Contribution Checklist](#contribution-checklist) + +--- + +## Overview + +### Purpose + +Container scripts (`ct/AppName.sh`) are **entry points for creating LXC containers** with specific applications pre-installed. They: + +1. Define container defaults (CPU, RAM, disk, OS) +2. Call the main build orchestrator (`build.func`) +3. Implement application-specific update mechanisms +4. Provide user-facing success messages + +### Execution Context + +``` +Proxmox Host + ↓ +ct/AppName.sh sourced (runs as root on host) + ↓ +build.func: Creates LXC container + runs install script inside + ↓ +install/AppName-install.sh (runs inside container) + ↓ +Container ready with app installed +``` + +### Key Integration Points + +- **build.func** - Main orchestrator (container creation, storage, variable management) +- **install.func** - Container-specific setup (OS update, package management) +- **tools.func** - Tool installation helpers (repositories, GitHub releases) +- **core.func** - UI/messaging functions (colors, spinners, validation) +- **error_handler.func** - Error handling and signal management + +--- + +## Architecture & Flow + +### Container Creation Flow + +``` +START: bash ct/pihole.sh + ↓ +[1] Set APP, var_*, defaults + ↓ +[2] header_info() β†’ Display ASCII art + ↓ +[3] variables() β†’ Parse arguments & load build.func + ↓ +[4] color() β†’ Setup ANSI codes + ↓ +[5] catch_errors() β†’ Setup trap handlers + ↓ +[6] install_script() β†’ Show mode menu (5 options) + ↓ + β”œβ”€ INSTALL_MODE="0" (Default) + β”œβ”€ INSTALL_MODE="1" (Advanced - 19-step wizard) + β”œβ”€ INSTALL_MODE="2" (User Defaults) + β”œβ”€ INSTALL_MODE="3" (App Defaults) + └─ INSTALL_MODE="4" (Settings Menu) + ↓ +[7] advanced_settings() β†’ Collect user configuration (if mode=1) + ↓ +[8] start() β†’ Confirm or re-edit settings + ↓ +[9] build_container() β†’ Create LXC + execute install script + ↓ +[10] description() β†’ Set container description + ↓ +[11] SUCCESS β†’ Display access URL + ↓ +END +``` + +### Default Values Precedence + +``` +Priority 1 (Highest): Environment Variables (var_cpu, var_ram, etc.) +Priority 2: App-Specific Defaults (/defaults/AppName.vars) +Priority 3: User Global Defaults (/default.vars) +Priority 4 (Lowest): Built-in Defaults (in build.func) +``` + +--- + +## File Structure + +### Minimal ct/AppName.sh Template + +``` +#!/usr/bin/env bash # [1] Shebang + # [2] Copyright/License +source <(curl -s .../misc/build.func) # [3] Import functions + # [4] APP metadata +APP="AppName" # [5] Default values +var_tags="tag1;tag2" +var_cpu="2" +var_ram="2048" +... + +header_info "$APP" # [6] Display header +variables # [7] Process arguments +color # [8] Setup colors +catch_errors # [9] Setup error handling + +function update_script() { ... } # [10] Update function (optional) + +start # [11] Launch container creation +build_container +description +msg_ok "Completed Successfully!\n" +``` + +--- + +## Complete Script Template + +### 1. File Header & Imports + +```bash +#!/usr/bin/env bash +# Copyright (c) 2021-2025 community-scripts ORG +# Author: YourUsername +# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE +# Source: https://github.com/example/project + +# Import main orchestrator +source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVE/raw/branch/main/misc/build.func) +``` + +> **⚠️ IMPORTANT**: Before opening a PR, change URL to `community-scripts` repo! + +### 2. Application Metadata + +```bash +# Application Configuration +APP="ApplicationName" +var_tags="tag1;tag2;tag3" # Max 3-4 tags, no spaces, semicolon-separated + +# Container Resources +var_cpu="2" # CPU cores +var_ram="2048" # RAM in MB +var_disk="10" # Disk in GB + +# Container Type & OS +var_os="debian" # Options: alpine, debian, ubuntu +var_version="12" # Alpine: 3.20+, Debian: 11-13, Ubuntu: 20.04+ +var_unprivileged="1" # 1=unprivileged (secure), 0=privileged (rarely needed) +``` + +**Variable Naming Convention**: +- Variables exposed to user: `var_*` (e.g., `var_cpu`, `var_hostname`, `var_ssh`) +- Internal variables: lowercase (e.g., `container_id`, `app_version`) + +### 3. Display & Initialization + +```bash +# Display header ASCII art +header_info "$APP" + +# Process command-line arguments and load configuration +variables + +# Setup ANSI color codes and formatting +color + +# Initialize error handling (trap ERR, EXIT, INT, TERM) +catch_errors +``` + +### 4. Update Function (Highly Recommended) + +```bash +function update_script() { + header_info + + # Always start with these checks + check_container_storage + check_container_resources + + # Verify app is installed + if [[ ! -d /opt/appname ]]; then + msg_error "No ${APP} Installation Found!" + exit + fi + + # Get latest version from GitHub + RELEASE=$(curl -fsSL https://api.github.com/repos/user/repo/releases/latest | \ + grep "tag_name" | awk '{print substr($2, 2, length($2)-3)}') + + # Compare with saved version + if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then + msg_info "Updating ${APP} to v${RELEASE}" + + # Backup user data + cp -r /opt/appname /opt/appname-backup + + # Perform update + cd /opt + wget -q "https://github.com/user/repo/releases/download/v${RELEASE}/app-${RELEASE}.tar.gz" + tar -xzf app-${RELEASE}.tar.gz + + # Restore user data + cp /opt/appname-backup/config/* /opt/appname/config/ + + # Cleanup + rm -rf app-${RELEASE}.tar.gz /opt/appname-backup + + # Save new version + echo "${RELEASE}" > /opt/${APP}_version.txt + + msg_ok "Updated ${APP} to v${RELEASE}" + else + msg_ok "No update required. ${APP} is already at v${RELEASE}." + fi + + exit +} +``` + +### 5. Script Launch + +```bash +# Start the container creation workflow +start + +# Build the container with selected configuration +build_container + +# Set container description/notes in Proxmox UI +description + +# Display success message +msg_ok "Completed Successfully!\n" +echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}" +echo -e "${INFO}${YW} Access it using the following URL:${CL}" +echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:8080${CL}" +``` + +--- + +## Function Reference + +### Core Functions (From build.func) + +#### `variables()` + +**Purpose**: Initialize container variables, load user arguments, setup orchestration + +**Triggered by**: Called automatically at script start + +**Behavior**: +1. Parse command-line arguments (if any) +2. Generate random UUID for session tracking +3. Load container storage from Proxmox +4. Initialize application-specific defaults +5. Setup SSH/environment configuration + +#### `start()` + +**Purpose**: Launch the container creation menu with 5 installation modes + +**Menu Options**: +``` +1. Default Installation (Quick setup, predefined settings) +2. Advanced Installation (19-step wizard with full control) +3. User Defaults (Load ~/.community-scripts/default.vars) +4. App Defaults (Load /defaults/AppName.vars) +5. Settings Menu (Interactive mode selection) +``` + +#### `build_container()` + +**Purpose**: Main orchestrator for LXC container creation + +**Operations**: +1. Validates all variables +2. Creates LXC container via `pct create` +3. Executes `install/AppName-install.sh` inside container +4. Monitors installation progress +5. Handles errors and rollback on failure + +#### `description()` + +**Purpose**: Set container description/notes visible in Proxmox UI + +--- + +## Advanced Features + +### 1. Custom Configuration Menus + +If your app has additional setup beyond standard vars: + +```bash +custom_app_settings() { + CONFIGURE_DB=$(whiptail --title "Database Setup" \ + --yesno "Would you like to configure a custom database?" 8 60) + + if [[ $? -eq 0 ]]; then + DB_HOST=$(whiptail --inputbox "Database Host:" 8 60 3>&1 1>&2 2>&3) + DB_PORT=$(whiptail --inputbox "Database Port:" 8 60 "3306" 3>&1 1>&2 2>&3) + fi +} + +custom_app_settings +``` + +### 2. Update Function Patterns + +Save installed version for update checks + +### 3. Health Check Functions + +Add custom validation: + +```bash +function health_check() { + header_info + + if [[ ! -d /opt/appname ]]; then + msg_error "Application not found!" + exit 1 + fi + + if ! systemctl is-active --quiet appname; then + msg_error "Application service not running" + exit 1 + fi + + msg_ok "Health check passed" +} +``` + +--- + +## Real Examples + +### Example 1: Simple Web App (Debian-based) + +```bash +#!/usr/bin/env bash +source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVE/raw/branch/main/misc/build.func) + +APP="Homarr" +var_tags="dashboard;homepage" +var_cpu="2" +var_ram="1024" +var_disk="5" +var_os="debian" +var_version="12" +var_unprivileged="1" + +header_info "$APP" +variables +color +catch_errors + +function update_script() { + # Update logic here +} + +start +build_container +description +msg_ok "Completed Successfully!\n" +``` + +--- + +## Troubleshooting + +### Container Creation Fails + +**Symptom**: `pct create` exits with error code 209 + +**Solution**: +```bash +# Check existing containers +pct list | grep CTID + +# Remove conflicting container +pct destroy CTID + +# Retry ct/AppName.sh +``` + +### Update Function Doesn't Detect New Version + +**Debug**: +```bash +# Check version file +cat /opt/AppName_version.txt + +# Test GitHub API +curl -fsSL https://api.github.com/repos/user/repo/releases/latest | grep tag_name +``` + +--- + +## Contribution Checklist + +Before submitting a PR: + +### Script Structure +- [ ] Shebang is `#!/usr/bin/env bash` +- [ ] Imports `build.func` from community-scripts repo +- [ ] Copyright header with author and source URL +- [ ] APP variable matches filename +- [ ] `var_tags` are semicolon-separated (no spaces) + +### Default Values +- [ ] `var_cpu` set appropriately (2-4 for most apps) +- [ ] `var_ram` set appropriately (1024-4096 MB minimum) +- [ ] `var_disk` sufficient for app + data (5-20 GB) +- [ ] `var_os` is realistic + +### Functions +- [ ] `update_script()` implemented +- [ ] Update function checks if app installed +- [ ] Proper error handling with `msg_error` + +### Testing +- [ ] Script tested with default installation +- [ ] Script tested with advanced (19-step) installation +- [ ] Update function tested on existing installation + +--- + +## Best Practices + +### βœ… DO: + +1. **Use meaningful defaults** +2. **Implement version tracking** +3. **Handle edge cases** +4. **Use proper messaging with msg_info/msg_ok/msg_error** + +### ❌ DON'T: + +1. **Hardcode versions** +2. **Use custom color codes** (use built-in variables) +3. **Forget error handling** +4. **Leave temporary files** + +--- + +**Last Updated**: December 2025 +**Compatibility**: ProxmoxVE with build.func v3+ diff --git a/docs/ct/README.md b/docs/ct/README.md new file mode 100644 index 000000000..09eac5f19 --- /dev/null +++ b/docs/ct/README.md @@ -0,0 +1,72 @@ +# Container Scripts Documentation (/ct) + +This directory contains comprehensive documentation for container creation scripts in the `/ct` directory. + +## Overview + +Container scripts (`ct/*.sh`) are the entry points for creating LXC containers in Proxmox VE. They run on the host and orchestrate the entire container creation process. + +## Documentation Structure + +Each script has standardized documentation following the project pattern. + +## Key Resources + +- **[DETAILED_GUIDE.md](DETAILED_GUIDE.md)** - Complete reference for creating ct scripts +- **[../contribution/README.md](../contribution/README.md)** - How to contribute +- **[../misc/build.func/](../misc/build.func/)** - Core orchestrator documentation + +## Container Creation Flow + +``` +ct/AppName.sh (host-side) + β”‚ + β”œβ”€ Calls: build.func (orchestrator) + β”‚ + β”œβ”€ Variables: var_cpu, var_ram, var_disk, var_os + β”‚ + └─ Creates: LXC Container + β”‚ + └─ Runs: install/appname-install.sh (inside) +``` + +## Available Scripts + +See `/ct` directory for all container creation scripts. Common examples: + +- `pihole.sh` - Pi-hole DNS/DHCP server +- `docker.sh` - Docker container runtime +- `wallabag.sh` - Article reading & archiving +- `nextcloud.sh` - Private cloud storage +- `debian.sh` - Basic Debian container +- And 30+ more... + +## Quick Start + +To understand how to create a container script: + +1. Read: [UPDATED_APP-ct.md](../UPDATED_APP-ct.md) +2. Study: A similar existing script in `/ct` +3. Copy template and customize +4. Test locally +5. Submit PR + +## Contributing a New Container + +1. Create `ct/myapp.sh` +2. Create `install/myapp-install.sh` +3. Follow template in [UPDATED_APP-ct.md](../UPDATED_APP-ct.md) +4. Test thoroughly +5. Submit PR with both files + +## Common Tasks + +- **Add new container application** β†’ [CONTRIBUTION_GUIDE.md](../CONTRIBUTION_GUIDE.md) +- **Debug container creation** β†’ [EXIT_CODES.md](../EXIT_CODES.md) +- **Understand build.func** β†’ [misc/build.func/](../misc/build.func/) +- **Development mode debugging** β†’ [DEV_MODE.md](../DEV_MODE.md) + +--- + +**Last Updated**: December 2025 +**Maintainers**: community-scripts team diff --git a/docs/install/DETAILED_GUIDE.md b/docs/install/DETAILED_GUIDE.md new file mode 100644 index 000000000..95484990b --- /dev/null +++ b/docs/install/DETAILED_GUIDE.md @@ -0,0 +1,646 @@ +# πŸ› οΈ **Application Installation Scripts (install/AppName-install.sh)** + +**Modern Guide to Writing In-Container Installation Scripts** + +> **Updated**: December 2025 +> **Context**: Integrated with tools.func, error_handler.func, and install.func +> **Examples Used**: `/install/pihole-install.sh`, `/install/mealie-install.sh` + +--- + +## πŸ“‹ Table of Contents + +- [Overview](#overview) +- [Execution Context](#execution-context) +- [File Structure](#file-structure) +- [Complete Script Template](#complete-script-template) +- [Installation Phases](#installation-phases) +- [Function Reference](#function-reference) +- [Best Practices](#best-practices) +- [Real Examples](#real-examples) +- [Troubleshooting](#troubleshooting) +- [Contribution Checklist](#contribution-checklist) + +--- + +## Overview + +### Purpose + +Installation scripts (`install/AppName-install.sh`) **run inside the LXC container** and are responsible for: + +1. Setting up the container OS (updates, packages) +2. Installing application dependencies +3. Downloading and configuring the application +4. Setting up services and systemd units +5. Creating version tracking files for updates +6. Generating credentials/configurations +7. Final cleanup and validation + +### Execution Flow + +``` +ct/AppName.sh (Proxmox Host) + ↓ +build_container() + ↓ +pct exec CTID bash -c "$(cat install/AppName-install.sh)" + ↓ +install/AppName-install.sh (Inside Container) + ↓ +Container Ready with App Installed +``` + +--- + +## Execution Context + +### Environment Variables Available + +```bash +# From Proxmox/Container +CTID # Container ID (100, 101, etc.) +PCT_OSTYPE # OS type (alpine, debian, ubuntu) +HOSTNAME # Container hostname + +# From build.func +FUNCTIONS_FILE_PATH # Bash functions library (core.func + tools.func) +VERBOSE # Verbose mode (yes/no) +STD # Standard redirection variable (silent/empty) + +# From install.func +APP # Application name +NSAPP # Normalized app name (lowercase, no spaces) +METHOD # Installation method (ct/install) +RANDOM_UUID # Session UUID for telemetry +``` + +--- + +## File Structure + +### Minimal install/AppName-install.sh Template + +```bash +#!/usr/bin/env bash # [1] Shebang + +# [2] Copyright/Metadata +# Copyright (c) 2021-2025 community-scripts ORG +# Author: YourUsername +# License: MIT +# Source: https://example.com + +# [3] Load functions +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +# [4] Installation steps +msg_info "Installing Dependencies" +$STD apt-get install -y package1 package2 +msg_ok "Installed Dependencies" + +# [5] Final setup +motd_ssh +customize +cleanup_lxc +``` + +--- + +## Complete Script Template + +### Phase 1: Header & Initialization + +```bash +#!/usr/bin/env bash +# Copyright (c) 2021-2025 community-scripts ORG +# Author: YourUsername +# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE +# Source: https://github.com/application/repo + +# Load all available functions (from core.func + tools.func) +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" + +# Initialize environment +color # Setup ANSI colors and icons +verb_ip6 # Configure IPv6 (if needed) +catch_errors # Setup error traps +setting_up_container # Verify OS is ready +network_check # Verify internet connectivity +update_os # Update packages (apk/apt) +``` + +### Phase 2: Dependency Installation + +```bash +msg_info "Installing Dependencies" +$STD apt-get install -y \ + curl \ + wget \ + git \ + nano \ + build-essential \ + libssl-dev \ + python3-dev +msg_ok "Installed Dependencies" +``` + +### Phase 3: Tool Setup (Using tools.func) + +```bash +# Setup specific tool versions +NODE_VERSION="22" setup_nodejs +PHP_VERSION="8.4" setup_php +PYTHON_VERSION="3.12" setup_uv +``` + +### Phase 4: Application Download & Setup + +```bash +# Download from GitHub +RELEASE=$(curl -fsSL https://api.github.com/repos/user/repo/releases/latest | \ + grep "tag_name" | awk '{print substr($2, 2, length($2)-3)}') + +wget -q "https://github.com/user/repo/releases/download/v${RELEASE}/app-${RELEASE}.tar.gz" +cd /opt +tar -xzf app-${RELEASE}.tar.gz +rm -f app-${RELEASE}.tar.gz +``` + +### Phase 5: Configuration Files + +```bash +# Using cat << EOF (multiline) +cat <<'EOF' >/etc/nginx/sites-available/appname +server { + listen 80; + server_name _; + root /opt/appname/public; + index index.php index.html; +} +EOF + +# Using sed for replacements +sed -i -e "s|^DB_HOST=.*|DB_HOST=localhost|" \ + -e "s|^DB_USER=.*|DB_USER=appuser|" \ + /opt/appname/.env +``` + +### Phase 6: Database Setup (If Needed) + +```bash +msg_info "Setting up Database" + +DB_NAME="appname_db" +DB_USER="appuser" +DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13) + +# For MySQL/MariaDB +mysql -u root < /opt/${APP}_version.txt + +# Or with additional metadata +cat > /opt/${APP}_version.txt < /opt/${APP}_version.txt +``` + +6. **Handle Alpine vs Debian Differences** +```bash +# βœ… Good: Detect OS +if grep -qi 'alpine' /etc/os-release; then + apk add package +else + apt-get install -y package +fi +``` + +### ❌ DON'T: + +1. **Hardcode Versions** +```bash +# ❌ Bad: Won't auto-update +wget https://example.com/app-1.2.3.tar.gz +``` + +2. **Use Root Without Password** +```bash +# ❌ Bad: Security risk +mysql -u root +``` + +3. **Forget Error Handling** +```bash +# ❌ Bad: Silent failures +wget https://example.com/file +tar -xzf file +``` + +4. **Leave Temporary Files** +```bash +# βœ… Always cleanup +rm -rf /opt/app-${RELEASE}.tar.gz +``` + +--- + +## Real Examples + +### Example 1: Node.js Application + +```bash +#!/usr/bin/env bash +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" + +color +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Node.js" +NODE_VERSION="22" setup_nodejs +msg_ok "Node.js installed" + +msg_info "Installing Application" +cd /opt +RELEASE=$(curl -fsSL https://api.github.com/repos/user/repo/releases/latest | \ + grep "tag_name" | awk '{print substr($2, 2, length($2)-3)}') +wget -q "https://github.com/user/repo/releases/download/v${RELEASE}/app.tar.gz" +tar -xzf app.tar.gz +echo "${RELEASE}" > /opt/app_version.txt +msg_ok "Application installed" + +systemctl enable --now app +cleanup_lxc +``` + +### Example 2: PHP Application with Database + +```bash +#!/usr/bin/env bash +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" + +color +catch_errors +setting_up_container +network_check +update_os + +PHP_VERSION="8.4" PHP_MODULE="bcmath,curl,pdo_mysql" setup_php +MARIADB_VERSION="11.4" setup_mariadb + +# Database setup +DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13) +mysql -u root < /opt/app/.env < .env < /opt/app_version.txt +``` + +### Phase 10: Final Cleanup +```bash +motd_ssh +customize +cleanup_lxc +``` + +## Contributing an Installation Script + +1. Create `ct/myapp.sh` (host script) +2. Create `install/myapp-install.sh` (container script) +3. Follow 10-phase pattern in [UPDATED_APP-install.md](../UPDATED_APP-install.md) +4. Test in actual container +5. Submit PR with both files + +## Common Tasks + +- **Create new installation script** β†’ [UPDATED_APP-install.md](../UPDATED_APP-install.md) +- **Install Node.js/PHP/Database** β†’ [misc/tools.func/](../misc/tools.func/) +- **Setup Alpine container** β†’ [misc/alpine-install.func/](../misc/alpine-install.func/) +- **Debug installation errors** β†’ [EXIT_CODES.md](../EXIT_CODES.md) +- **Use dev mode** β†’ [DEV_MODE.md](../DEV_MODE.md) + +## Alpine vs Debian + +- **Debian-based** β†’ Use `tools.func`, `install.func`, `systemctl` +- **Alpine-based** β†’ Use `alpine-tools.func`, `alpine-install.func`, `rc-service` + +--- + +**Last Updated**: December 2025 +**Maintainers**: community-scripts team diff --git a/docs/misc/README.md b/docs/misc/README.md new file mode 100644 index 000000000..291ded111 --- /dev/null +++ b/docs/misc/README.md @@ -0,0 +1,283 @@ +# Misc Documentation + +This directory contains comprehensive documentation for all function libraries and components of the Proxmox Community Scripts project. Each section is organized as a dedicated subdirectory with detailed references, examples, and integration guides. + +--- + +## πŸ—οΈ **Core Function Libraries** + +### πŸ“ [build.func/](./build.func/) +**Core LXC Container Orchestration** - Main orchestrator for Proxmox LXC container creation + +**Contents:** +- BUILD_FUNC_FLOWCHART.md - Visual execution flows and decision trees +- BUILD_FUNC_ARCHITECTURE.md - System architecture and design +- BUILD_FUNC_ENVIRONMENT_VARIABLES.md - Complete environment variable reference +- BUILD_FUNC_FUNCTIONS_REFERENCE.md - Alphabetical function reference +- BUILD_FUNC_EXECUTION_FLOWS.md - Detailed execution flows +- BUILD_FUNC_USAGE_EXAMPLES.md - Practical usage examples +- README.md - Overview and quick reference + +**Key Functions**: `variables()`, `start()`, `build_container()`, `build_defaults()`, `advanced_settings()` + +--- + +### πŸ“ [core.func/](./core.func/) +**System Utilities & Foundation** - Essential utility functions and system checks + +**Contents:** +- CORE_FLOWCHART.md - Visual execution flows +- CORE_FUNCTIONS_REFERENCE.md - Complete function reference +- CORE_INTEGRATION.md - Integration points +- CORE_USAGE_EXAMPLES.md - Practical examples +- README.md - Overview and quick reference + +**Key Functions**: `color()`, `msg_info()`, `msg_ok()`, `msg_error()`, `root_check()`, `pve_check()`, `parse_dev_mode()` + +--- + +### πŸ“ [error_handler.func/](./error_handler.func/) +**Error Handling & Signal Management** - Comprehensive error handling and signal trapping + +**Contents:** +- ERROR_HANDLER_FLOWCHART.md - Visual error handling flows +- ERROR_HANDLER_FUNCTIONS_REFERENCE.md - Function reference +- ERROR_HANDLER_INTEGRATION.md - Integration with other components +- ERROR_HANDLER_USAGE_EXAMPLES.md - Practical examples +- README.md - Overview and quick reference + +**Key Functions**: `catch_errors()`, `error_handler()`, `explain_exit_code()`, `signal_handler()` + +--- + +### πŸ“ [api.func/](./api.func/) +**Proxmox API Integration** - API communication and diagnostic reporting + +**Contents:** +- API_FLOWCHART.md - API communication flows +- API_FUNCTIONS_REFERENCE.md - Function reference +- API_INTEGRATION.md - Integration points +- API_USAGE_EXAMPLES.md - Practical examples +- README.md - Overview and quick reference + +**Key Functions**: `post_to_api()`, `post_update_to_api()`, `get_error_description()` + +--- + +## πŸ“¦ **Installation & Setup Function Libraries** + +### πŸ“ [install.func/](./install.func/) +**Container Installation Workflow** - Installation orchestration for container-internal setup + +**Contents:** +- INSTALL_FUNC_FLOWCHART.md - Installation workflow diagrams +- INSTALL_FUNC_FUNCTIONS_REFERENCE.md - Complete function reference +- INSTALL_FUNC_INTEGRATION.md - Integration with build and tools +- INSTALL_FUNC_USAGE_EXAMPLES.md - Practical examples +- README.md - Overview and quick reference + +**Key Functions**: `setting_up_container()`, `network_check()`, `update_os()`, `motd_ssh()`, `cleanup_lxc()` + +--- + +### πŸ“ [tools.func/](./tools.func/) +**Package & Tool Installation** - Robust package management and 30+ tool installation functions + +**Contents:** +- TOOLS_FUNC_FLOWCHART.md - Package management flows +- TOOLS_FUNC_FUNCTIONS_REFERENCE.md - 30+ function reference +- TOOLS_FUNC_INTEGRATION.md - Integration with install workflows +- TOOLS_FUNC_USAGE_EXAMPLES.md - Practical examples +- TOOLS_FUNC_ENVIRONMENT_VARIABLES.md - Configuration reference +- README.md - Overview and quick reference + +**Key Functions**: `setup_nodejs()`, `setup_php()`, `setup_mariadb()`, `setup_docker()`, `setup_deb822_repo()`, `pkg_install()`, `pkg_update()` + +--- + +### πŸ“ [alpine-install.func/](./alpine-install.func/) +**Alpine Container Setup** - Alpine Linux-specific installation functions + +**Contents:** +- ALPINE_INSTALL_FUNC_FLOWCHART.md - Alpine setup flows +- ALPINE_INSTALL_FUNC_FUNCTIONS_REFERENCE.md - Function reference +- ALPINE_INSTALL_FUNC_INTEGRATION.md - Integration points +- ALPINE_INSTALL_FUNC_USAGE_EXAMPLES.md - Practical examples +- README.md - Overview and quick reference + +**Key Functions**: `update_os()` (apk version), `verb_ip6()`, `motd_ssh()` (Alpine), `customize()` + +--- + +### πŸ“ [alpine-tools.func/](./alpine-tools.func/) +**Alpine Tool Installation** - Alpine-specific package and tool installation + +**Contents:** +- ALPINE_TOOLS_FUNC_FLOWCHART.md - Alpine package flows +- ALPINE_TOOLS_FUNC_FUNCTIONS_REFERENCE.md - Function reference +- ALPINE_TOOLS_FUNC_INTEGRATION.md - Integration with Alpine workflows +- ALPINE_TOOLS_FUNC_USAGE_EXAMPLES.md - Practical examples +- README.md - Overview and quick reference + +**Key Functions**: `apk_add()`, `apk_update()`, `apk_del()`, `add_community_repo()`, Alpine tool setup functions + +--- + +### πŸ“ [cloud-init.func/](./cloud-init.func/) +**VM Cloud-Init Configuration** - Cloud-init and VM provisioning functions + +**Contents:** +- CLOUD_INIT_FUNC_FLOWCHART.md - Cloud-init flows +- CLOUD_INIT_FUNC_FUNCTIONS_REFERENCE.md - Function reference +- CLOUD_INIT_FUNC_INTEGRATION.md - Integration points +- CLOUD_INIT_FUNC_USAGE_EXAMPLES.md - Practical examples +- README.md - Overview and quick reference + +**Key Functions**: `generate_cloud_init()`, `generate_user_data()`, `setup_ssh_keys()`, `setup_static_ip()` + +--- + +## πŸ”— **Function Library Relationships** + +``` +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ Container Creation Flow β”‚ +β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ +β”‚ β”‚ +β”‚ ct/AppName.sh β”‚ +β”‚ ↓ (sources) β”‚ +β”‚ build.func β”‚ +β”‚ β”œβ”€ variables() β”‚ +β”‚ β”œβ”€ build_container() β”‚ +β”‚ └─ advanced_settings() β”‚ +β”‚ ↓ (calls pct create with) β”‚ +β”‚ install/appname-install.sh β”‚ +β”‚ ↓ (sources) β”‚ +β”‚ β”œβ”€ core.func (colors, messaging) β”‚ +β”‚ β”œβ”€ error_handler.func (error trapping) β”‚ +β”‚ β”œβ”€ install.func (setup/network) β”‚ +β”‚ └─ tools.func (packages/tools) β”‚ +β”‚ β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ Alpine Container Flow β”‚ +β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ +β”‚ β”‚ +β”‚ install/appname-install.sh (Alpine) β”‚ +β”‚ ↓ (sources) β”‚ +β”‚ β”œβ”€ core.func (colors) β”‚ +β”‚ β”œβ”€ error_handler.func (errors) β”‚ +β”‚ β”œβ”€ alpine-install.func (apk setup) β”‚ +β”‚ └─ alpine-tools.func (apk tools) β”‚ +β”‚ β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ VM Provisioning Flow β”‚ +β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ +β”‚ β”‚ +β”‚ vm/OsName-vm.sh β”‚ +β”‚ ↓ (uses) β”‚ +β”‚ cloud-init.func β”‚ +β”‚ β”œβ”€ generate_cloud_init() β”‚ +β”‚ β”œβ”€ setup_ssh_keys() β”‚ +β”‚ └─ configure_network() β”‚ +β”‚ β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +``` + +--- + +## πŸ“Š **Documentation Quick Stats** + +| Library | Files | Functions | Status | +|---------|:---:|:---:|:---:| +| build.func | 7 | 50+ | βœ… Complete | +| core.func | 5 | 20+ | βœ… Complete | +| error_handler.func | 5 | 10+ | βœ… Complete | +| api.func | 5 | 5+ | βœ… Complete | +| install.func | 5 | 8+ | βœ… Complete | +| tools.func | 6 | 30+ | βœ… Complete | +| alpine-install.func | 5 | 6+ | βœ… Complete | +| alpine-tools.func | 5 | 15+ | βœ… Complete | +| cloud-init.func | 5 | 12+ | βœ… Complete | + +**Total**: 9 function libraries, 48 documentation files, 150+ functions + +--- + +## πŸš€ **Getting Started** + +### For Container Creation Scripts +Start with: **[build.func/](./build.func/)** β†’ **[tools.func/](./tools.func/)** β†’ **[install.func/](./install.func/)** + +### For Alpine Containers +Start with: **[alpine-install.func/](./alpine-install.func/)** β†’ **[alpine-tools.func/](./alpine-tools.func/)** + +### For VM Provisioning +Start with: **[cloud-init.func/](./cloud-init.func/)** + +### For Troubleshooting +Start with: **[error_handler.func/](./error_handler.func/)** β†’ **[EXIT_CODES.md](../EXIT_CODES.md)** + +--- + +## πŸ“š **Related Top-Level Documentation** + +- **[CONTRIBUTION_GUIDE.md](../CONTRIBUTION_GUIDE.md)** - How to contribute to ProxmoxVE +- **[UPDATED_APP-ct.md](../UPDATED_APP-ct.md)** - Container script guide +- **[UPDATED_APP-install.md](../UPDATED_APP-install.md)** - Installation script guide +- **[DEFAULTS_SYSTEM_GUIDE.md](../DEFAULTS_SYSTEM_GUIDE.md)** - Configuration system +- **[TECHNICAL_REFERENCE.md](../TECHNICAL_REFERENCE.md)** - Architecture reference +- **[EXIT_CODES.md](../EXIT_CODES.md)** - Complete exit code reference +- **[DEV_MODE.md](../DEV_MODE.md)** - Development debugging modes +- **[CHANGELOG_MISC.md](../CHANGELOG_MISC.md)** - Change history + +--- + +## πŸ”„ **Standardized Documentation Structure** + +Each function library follows the same documentation pattern: + +``` +function-library/ +β”œβ”€β”€ README.md # Quick reference & overview +β”œβ”€β”€ FUNCTION_LIBRARY_FLOWCHART.md # Visual execution flows +β”œβ”€β”€ FUNCTION_LIBRARY_FUNCTIONS_REFERENCE.md # Alphabetical reference +β”œβ”€β”€ FUNCTION_LIBRARY_INTEGRATION.md # Integration points +β”œβ”€β”€ FUNCTION_LIBRARY_USAGE_EXAMPLES.md # Practical examples +└── [FUNCTION_LIBRARY_ENVIRONMENT_VARIABLES.md] # (if applicable) +``` + +**Advantages**: +- βœ… Consistent navigation across all libraries +- βœ… Quick reference sections in each README +- βœ… Visual flowcharts for understanding +- βœ… Complete function references +- βœ… Real-world usage examples +- βœ… Integration guides for connecting libraries + +--- + +## πŸ“ **Documentation Standards** + +All documentation follows these standards: + +1. **README.md** - Quick overview, key features, quick reference +2. **FLOWCHART.md** - ASCII flowcharts and visual diagrams +3. **FUNCTIONS_REFERENCE.md** - Every function with full details +4. **INTEGRATION.md** - How this library connects to others +5. **USAGE_EXAMPLES.md** - Copy-paste ready examples +6. **ENVIRONMENT_VARIABLES.md** - (if applicable) Configuration reference + +--- + +## βœ… **Last Updated**: December 2025 +**Maintainers**: community-scripts team +**License**: MIT +**Status**: All 9 libraries fully documented and standardized + +--- + +*This directory contains specialized documentation for specific components of the Proxmox Community Scripts project.* diff --git a/docs/misc/alpine-install.func/ALPINE_INSTALL_FUNC_FLOWCHART.md b/docs/misc/alpine-install.func/ALPINE_INSTALL_FUNC_FLOWCHART.md new file mode 100644 index 000000000..072d613fc --- /dev/null +++ b/docs/misc/alpine-install.func/ALPINE_INSTALL_FUNC_FLOWCHART.md @@ -0,0 +1,29 @@ +# alpine-install.func Flowchart + +Alpine container initialization flow (apk-based, OpenRC init system). + +## Alpine Container Setup Flow + +``` +Alpine Container Started + ↓ +setting_up_container() + ↓ +verb_ip6() [optional - IPv6] + ↓ +update_os() [apk update/upgrade] + ↓ +network_check() + ↓ +Application Installation + ↓ +motd_ssh() + ↓ +customize() + ↓ +cleanup_lxc() + ↓ +Complete βœ“ +``` + +**Last Updated**: December 2025 diff --git a/docs/misc/alpine-install.func/ALPINE_INSTALL_FUNC_FUNCTIONS_REFERENCE.md b/docs/misc/alpine-install.func/ALPINE_INSTALL_FUNC_FUNCTIONS_REFERENCE.md new file mode 100644 index 000000000..9f2cc28df --- /dev/null +++ b/docs/misc/alpine-install.func/ALPINE_INSTALL_FUNC_FUNCTIONS_REFERENCE.md @@ -0,0 +1,30 @@ +# alpine-install.func Functions Reference + +Alpine Linux-specific installation functions (apk-based, OpenRC). + +## Core Functions + +### setting_up_container() +Initialize Alpine container setup. + +### update_os() +Update Alpine packages via `apk update && apk upgrade`. + +### verb_ip6() +Enable IPv6 on Alpine with persistent configuration. + +### network_check() +Verify network connectivity in Alpine. + +### motd_ssh() +Configure SSH daemon and MOTD on Alpine. + +### customize() +Apply Alpine-specific customizations. + +### cleanup_lxc() +Final cleanup (Alpine-specific). + +--- + +**Last Updated**: December 2025 diff --git a/docs/misc/alpine-install.func/ALPINE_INSTALL_FUNC_INTEGRATION.md b/docs/misc/alpine-install.func/ALPINE_INSTALL_FUNC_INTEGRATION.md new file mode 100644 index 000000000..8fe0f2cd3 --- /dev/null +++ b/docs/misc/alpine-install.func/ALPINE_INSTALL_FUNC_INTEGRATION.md @@ -0,0 +1,14 @@ +# alpine-install.func Integration Guide + +Integration of alpine-install.func with Alpine container workflows. + +## Alpine-Specific Integration + +Alpine containers use: +- `apk` instead of `apt-get` +- `OpenRC` instead of `systemd` +- Alpine-specific package names + +--- + +**Last Updated**: December 2025 diff --git a/docs/misc/alpine-install.func/ALPINE_INSTALL_FUNC_USAGE_EXAMPLES.md b/docs/misc/alpine-install.func/ALPINE_INSTALL_FUNC_USAGE_EXAMPLES.md new file mode 100644 index 000000000..15ff05630 --- /dev/null +++ b/docs/misc/alpine-install.func/ALPINE_INSTALL_FUNC_USAGE_EXAMPLES.md @@ -0,0 +1,24 @@ +# alpine-install.func Usage Examples + +Basic examples for Alpine container installation. + +### Example: Basic Alpine Setup + +```bash +#!/usr/bin/env bash +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" + +setting_up_container +update_os + +# Install Alpine packages +apk add --no-cache curl wget git + +motd_ssh +customize +cleanup_lxc +``` + +--- + +**Last Updated**: December 2025 diff --git a/docs/misc/alpine-install.func/README.md b/docs/misc/alpine-install.func/README.md new file mode 100644 index 000000000..dedb033d6 --- /dev/null +++ b/docs/misc/alpine-install.func/README.md @@ -0,0 +1,273 @@ +# alpine-install.func Documentation + +## Overview + +The `alpine-install.func` file provides Alpine Linux-specific installation and configuration functions for LXC containers. It complements the standard `install.func` with Alpine-specific operations using the apk package manager instead of apt. + +## Purpose and Use Cases + +- **Alpine Container Setup**: Initialize Alpine Linux containers with proper configuration +- **IPv6 Management**: Enable or disable IPv6 in Alpine with persistent configuration +- **Network Verification**: Verify connectivity in Alpine environments +- **SSH Configuration**: Setup SSH daemon on Alpine +- **Auto-Login Setup**: Configure passwordless root login for Alpine containers +- **Package Management**: Safe apk operations with error handling + +## Quick Reference + +### Key Function Groups +- **Initialization**: `setting_up_container()` - Alpine setup message +- **Network**: `verb_ip6()`, `network_check()` - IPv6 and connectivity +- **OS Configuration**: `update_os()` - Alpine package updates +- **SSH/MOTD**: `motd_ssh()` - SSH and login message setup +- **Container Customization**: `customize()`, `cleanup_lxc()` - Final setup + +### Dependencies +- **External**: `apk`, `curl`, `wget`, `ping` +- **Internal**: Uses functions from `core.func`, `error_handler.func` + +### Integration Points +- Used by: Alpine-based install scripts (alpine.sh, alpine-ntfy.sh, etc.) +- Uses: Environment variables from build.func +- Provides: Alpine-specific installation and management services + +## Documentation Files + +### πŸ“Š [ALPINE_INSTALL_FUNC_FLOWCHART.md](./ALPINE_INSTALL_FUNC_FLOWCHART.md) +Visual execution flows showing Alpine container initialization and setup workflows. + +### πŸ“š [ALPINE_INSTALL_FUNC_FUNCTIONS_REFERENCE.md](./ALPINE_INSTALL_FUNC_FUNCTIONS_REFERENCE.md) +Complete alphabetical reference of all functions with parameters and usage details. + +### πŸ’‘ [ALPINE_INSTALL_FUNC_USAGE_EXAMPLES.md](./ALPINE_INSTALL_FUNC_USAGE_EXAMPLES.md) +Practical examples showing how to use Alpine installation functions. + +### πŸ”— [ALPINE_INSTALL_FUNC_INTEGRATION.md](./ALPINE_INSTALL_FUNC_INTEGRATION.md) +How alpine-install.func integrates with standard install workflows. + +## Key Features + +### Alpine-Specific Functions +- **apk Package Manager**: Alpine package operations (instead of apt-get) +- **OpenRC Support**: Alpine uses OpenRC init instead of systemd +- **Lightweight Setup**: Minimal dependencies appropriate for Alpine +- **IPv6 Configuration**: Persistent IPv6 settings via `/etc/network/interfaces` + +### Network & Connectivity +- **IPv6 Toggle**: Enable/disable with persistent configuration +- **Connectivity Check**: Verify internet access in Alpine +- **DNS Verification**: Resolve domain names correctly +- **Retry Logic**: Automatic recovery from transient failures + +### SSH & Auto-Login +- **SSH Daemon**: Setup and start sshd on Alpine +- **Root Keys**: Configure root SSH access +- **Auto-Login**: Optional automatic login without password +- **MOTD**: Custom login message on Alpine + +## Function Categories + +### πŸ”Ή Core Functions +- `setting_up_container()` - Alpine container setup message +- `update_os()` - Update Alpine packages via apk +- `verb_ip6()` - Enable/disable IPv6 persistently +- `network_check()` - Verify network connectivity + +### πŸ”Ή SSH & Configuration Functions +- `motd_ssh()` - Configure SSH daemon on Alpine +- `customize()` - Apply Alpine-specific customizations +- `cleanup_lxc()` - Final cleanup + +### πŸ”Ή Service Management (OpenRC) +- `rc-update` - Enable/disable services for Alpine +- `rc-service` - Start/stop services on Alpine +- Service configuration files in `/etc/init.d/` + +## Differences from Debian Install + +| Feature | Debian (install.func) | Alpine (alpine-install.func) | +|---------|:---:|:---:| +| Package Manager | apt-get | apk | +| Init System | systemd | OpenRC | +| SSH Service | systemctl | rc-service | +| Config Files | /etc/systemd/ | /etc/init.d/ | +| Network Config | /etc/network/ or Netplan | /etc/network/interfaces | +| IPv6 Setup | netplan files | /etc/network/interfaces | +| Auto-Login | getty override | `/etc/inittab` or shell config | +| Size | ~200MB | ~100MB | + +## Execution Flow for Alpine + +``` +Alpine Container Started + ↓ +source $FUNCTIONS_FILE_PATH + ↓ +setting_up_container() ← Alpine setup message + ↓ +update_os() ← apk update + ↓ +verb_ip6() ← IPv6 configuration (optional) + ↓ +network_check() ← Verify connectivity + ↓ +[Application-Specific Installation] + ↓ +motd_ssh() ← Configure SSH/MOTD +customize() ← Apply customizations + ↓ +cleanup_lxc() ← Final cleanup + ↓ +Alpine Installation Complete +``` + +## Common Usage Patterns + +### Basic Alpine Setup +```bash +#!/usr/bin/env bash +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" +setting_up_container +update_os + +# Install Alpine-specific packages +apk add --no-cache curl wget git + +# ... application installation ... + +motd_ssh +customize +cleanup_lxc +``` + +### With IPv6 Enabled +```bash +#!/usr/bin/env bash +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" +setting_up_container +verb_ip6 +update_os +network_check + +# ... application installation ... + +motd_ssh +customize +cleanup_lxc +``` + +### Installing Services +```bash +#!/usr/bin/env bash +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" +setting_up_container +update_os + +# Install via apk +apk add --no-cache nginx + +# Enable and start service on Alpine +rc-update add nginx +rc-service nginx start + +motd_ssh +customize +cleanup_lxc +``` + +## Best Practices + +### βœ… DO +- Use `apk add --no-cache` to reduce image size +- Enable IPv6 if application needs it (`verb_ip6`) +- Use `rc-service` for service management on Alpine +- Check `/etc/network/interfaces` for IPv6 persistence +- Test network connectivity before critical operations +- Use `$STD` for output suppression in production + +### ❌ DON'T +- Use `apt-get` commands (Alpine doesn't have apt) +- Use `systemctl` (Alpine uses OpenRC, not systemd) +- Use `service` command (it may not exist on Alpine) +- Assume systemd exists on Alpine +- Forget to add `--no-cache` flag to `apk add` +- Hardcode paths from Debian (different on Alpine) + +## Alpine-Specific Considerations + +### Package Names +Some packages have different names on Alpine: +```bash +# Debian β†’ Alpine +# curl β†’ curl (same) +# wget β†’ wget (same) +# python3 β†’ python3 (same) +# libpq5 β†’ postgresql-client +# libmariadb3 β†’ mariadb-client +``` + +### Service Management +```bash +# Debian (systemd) β†’ Alpine (OpenRC) +systemctl start nginx β†’ rc-service nginx start +systemctl enable nginx β†’ rc-update add nginx +systemctl status nginx β†’ rc-service nginx status +``` + +### Network Configuration +```bash +# Debian (Netplan) β†’ Alpine (/etc/network/interfaces) +/etc/netplan/01-*.yaml β†’ /etc/network/interfaces +netplan apply β†’ Configure directly in interfaces + +# Enable IPv6 persistently on Alpine: +# Add to /etc/network/interfaces: +# iface eth0 inet6 static +# address +``` + +## Troubleshooting + +### "apk command not found" +- This is Alpine Linux, not Debian +- Install packages with `apk add` instead of `apt-get install` +- Example: `apk add --no-cache curl wget` + +### "IPv6 not persisting after reboot" +- IPv6 must be configured in `/etc/network/interfaces` +- The `verb_ip6()` function handles this automatically +- Verify: `cat /etc/network/interfaces` + +### "Service won't start on Alpine" +- Alpine uses OpenRC, not systemd +- Use `rc-service nginx start` instead of `systemctl start nginx` +- Enable service: `rc-update add nginx` +- Check logs: `/var/log/` or `rc-service nginx status` + +### "Container too large" +- Alpine should be much smaller than Debian +- Verify using `apk add --no-cache` (removes package cache) +- Example: `apk add --no-cache nginx` (not `apk add nginx`) + +## Related Documentation + +- **[alpine-tools.func/](../alpine-tools.func/)** - Alpine tool installation +- **[install.func/](../install.func/)** - Standard installation functions +- **[core.func/](../core.func/)** - Utility functions +- **[error_handler.func/](../error_handler.func/)** - Error handling +- **[UPDATED_APP-install.md](../../UPDATED_APP-install.md)** - Application script guide + +## Recent Updates + +### Version 2.0 (Dec 2025) +- βœ… Enhanced IPv6 persistence configuration +- βœ… Improved OpenRC service management +- βœ… Better apk error handling +- βœ… Added Alpine-specific best practices documentation +- βœ… Streamlined SSH setup for Alpine + +--- + +**Last Updated**: December 2025 +**Maintainers**: community-scripts team +**License**: MIT diff --git a/docs/misc/alpine-tools.func/ALPINE_TOOLS_FUNC_FLOWCHART.md b/docs/misc/alpine-tools.func/ALPINE_TOOLS_FUNC_FLOWCHART.md new file mode 100644 index 000000000..9c5f9235b --- /dev/null +++ b/docs/misc/alpine-tools.func/ALPINE_TOOLS_FUNC_FLOWCHART.md @@ -0,0 +1,25 @@ +# alpine-tools.func Flowchart + +Alpine tool installation and package management flow. + +## Tool Installation on Alpine + +``` +apk_update() + ↓ +add_community_repo() [optional] + ↓ +apk_add PACKAGES + ↓ +Tool Installation + ↓ +rc-service start + ↓ +rc-update add [enable at boot] + ↓ +Complete βœ“ +``` + +--- + +**Last Updated**: December 2025 diff --git a/docs/misc/alpine-tools.func/ALPINE_TOOLS_FUNC_FUNCTIONS_REFERENCE.md b/docs/misc/alpine-tools.func/ALPINE_TOOLS_FUNC_FUNCTIONS_REFERENCE.md new file mode 100644 index 000000000..8d653e97b --- /dev/null +++ b/docs/misc/alpine-tools.func/ALPINE_TOOLS_FUNC_FUNCTIONS_REFERENCE.md @@ -0,0 +1,31 @@ +# alpine-tools.func Functions Reference + +Alpine-specific tool installation functions. + +## Core Functions + +### apk_update() +Update Alpine package lists. + +### apk_add(PACKAGES) +Install Alpine packages. + +### apk_del(PACKAGES) +Remove Alpine packages. + +### add_community_repo() +Enable Alpine community repository. + +### add_testing_repo() +Enable Alpine testing repository. + +### Alpine Tool Functions +- `setup_nodejs()` - Alpine Node.js +- `setup_php()` - Alpine PHP +- `setup_mariadb()` - Alpine MariaDB +- `setup_postgresql()` - Alpine PostgreSQL +- (+ more Alpine-specific setups) + +--- + +**Last Updated**: December 2025 diff --git a/docs/misc/alpine-tools.func/ALPINE_TOOLS_FUNC_INTEGRATION.md b/docs/misc/alpine-tools.func/ALPINE_TOOLS_FUNC_INTEGRATION.md new file mode 100644 index 000000000..ac30a73be --- /dev/null +++ b/docs/misc/alpine-tools.func/ALPINE_TOOLS_FUNC_INTEGRATION.md @@ -0,0 +1,7 @@ +# alpine-tools.func Integration Guide + +Alpine tool installation integration with container workflows. + +--- + +**Last Updated**: December 2025 diff --git a/docs/misc/alpine-tools.func/ALPINE_TOOLS_FUNC_USAGE_EXAMPLES.md b/docs/misc/alpine-tools.func/ALPINE_TOOLS_FUNC_USAGE_EXAMPLES.md new file mode 100644 index 000000000..e2b88204d --- /dev/null +++ b/docs/misc/alpine-tools.func/ALPINE_TOOLS_FUNC_USAGE_EXAMPLES.md @@ -0,0 +1,19 @@ +# alpine-tools.func Usage Examples + +Examples for Alpine tool installation. + +### Example: Alpine Setup with Tools + +```bash +#!/usr/bin/env bash +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" + +apk_update +setup_nodejs "20" +setup_php "8.3" +setup_mariadb "11" +``` + +--- + +**Last Updated**: December 2025 diff --git a/docs/misc/alpine-tools.func/README.md b/docs/misc/alpine-tools.func/README.md new file mode 100644 index 000000000..20ca097a7 --- /dev/null +++ b/docs/misc/alpine-tools.func/README.md @@ -0,0 +1,297 @@ +# alpine-tools.func Documentation + +## Overview + +The `alpine-tools.func` file provides Alpine Linux-specific tool installation functions for package and service management within Alpine LXC containers. It complements `tools.func` with Alpine-specific implementations using the apk package manager. + +## Purpose and Use Cases + +- **Alpine Tool Installation**: Install services and tools using apk on Alpine +- **Package Management**: Safe apk operations with error handling +- **Service Setup**: Install and configure common services on Alpine +- **Dependency Management**: Handle Alpine-specific package dependencies +- **Repository Management**: Setup and manage Alpine package repositories + +## Quick Reference + +### Key Function Groups +- **Package Operations**: Alpine-specific apk commands with error handling +- **Service Installation**: Install databases, web servers, tools on Alpine +- **Repository Setup**: Configure Alpine community and testing repositories +- **Tool Setup**: Install development tools and utilities + +### Dependencies +- **External**: `apk`, `curl`, `wget` +- **Internal**: Uses functions from `core.func`, `error_handler.func` + +### Integration Points +- Used by: Alpine-based application install scripts +- Uses: Environment variables from build.func +- Provides: Alpine package and tool installation services + +## Documentation Files + +### πŸ“Š [ALPINE_TOOLS_FUNC_FLOWCHART.md](./ALPINE_TOOLS_FUNC_FLOWCHART.md) +Visual execution flows for package operations and tool installation on Alpine. + +### πŸ“š [ALPINE_TOOLS_FUNC_FUNCTIONS_REFERENCE.md](./ALPINE_TOOLS_FUNC_FUNCTIONS_REFERENCE.md) +Complete alphabetical reference of all Alpine tool functions. + +### πŸ’‘ [ALPINE_TOOLS_FUNC_USAGE_EXAMPLES.md](./ALPINE_TOOLS_FUNC_USAGE_EXAMPLES.md) +Practical examples for common Alpine installation patterns. + +### πŸ”— [ALPINE_TOOLS_FUNC_INTEGRATION.md](./ALPINE_TOOLS_FUNC_INTEGRATION.md) +How alpine-tools.func integrates with Alpine installation workflows. + +## Key Features + +### Alpine Package Management +- **apk Add**: Safe package installation with error handling +- **apk Update**: Update package lists with retry logic +- **apk Del**: Remove packages and dependencies +- **Repository Configuration**: Add community and testing repos + +### Alpine Tool Coverage +- **Web Servers**: nginx, lighttpd +- **Databases**: mariadb, postgresql, sqlite +- **Development**: gcc, make, git, node.js (via apk) +- **Services**: sshd, docker, podman +- **Utilities**: curl, wget, htop, vim + +### Error Handling +- **Retry Logic**: Automatic recovery from transient failures +- **Dependency Resolution**: Handle missing dependencies +- **Lock Management**: Wait for apk locks to release +- **Error Reporting**: Clear error messages + +## Function Categories + +### πŸ”Ή Package Management +- `apk_update()` - Update Alpine packages with retry +- `apk_add()` - Install packages safely +- `apk_del()` - Remove packages completely + +### πŸ”Ή Repository Functions +- `add_community_repo()` - Enable community repositories +- `add_testing_repo()` - Enable testing repositories +- `setup_apk_repo()` - Configure custom apk repositories + +### πŸ”Ή Service Installation Functions +- `setup_nginx()` - Install and configure nginx +- `setup_mariadb()` - Install MariaDB on Alpine +- `setup_postgresql()` - Install PostgreSQL +- `setup_docker()` - Install Docker on Alpine +- `setup_nodejs()` - Install Node.js from Alpine repos + +### πŸ”Ή Development Tools +- `setup_build_tools()` - Install gcc, make, build-essential +- `setup_git()` - Install git version control +- `setup_python()` - Install Python 3 and pip + +## Alpine vs Debian Package Differences + +| Package | Debian | Alpine | +|---------|:---:|:---:| +| nginx | `apt-get install nginx` | `apk add nginx` | +| mariadb | `apt-get install mariadb-server` | `apk add mariadb` | +| PostgreSQL | `apt-get install postgresql` | `apk add postgresql` | +| Node.js | `apt-get install nodejs npm` | `apk add nodejs npm` | +| Docker | Special setup | `apk add docker` | +| Python | `apt-get install python3 python3-pip` | `apk add python3 py3-pip` | + +## Common Usage Patterns + +### Basic Alpine Tool Installation +```bash +#!/usr/bin/env bash +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" + +# Update package lists +apk_update + +# Install nginx +apk_add nginx + +# Start service +rc-service nginx start +rc-update add nginx +``` + +### With Community Repository +```bash +#!/usr/bin/env bash +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" + +# Enable community repo for more packages +add_community_repo + +# Update and install +apk_update +apk_add postgresql postgresql-client + +# Start service +rc-service postgresql start +``` + +### Development Environment +```bash +#!/usr/bin/env bash +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" + +# Install build tools +setup_build_tools +setup_git +setup_nodejs "20" + +# Install application +git clone https://example.com/app +cd app +npm install +``` + +## Best Practices + +### βœ… DO +- Always use `apk add --no-cache` to keep images small +- Call `apk_update()` before installing packages +- Use community repository for more packages (`add_community_repo`) +- Handle apk locks gracefully with retry logic +- Use `$STD` variable for output control +- Check if tool already installed before reinstalling + +### ❌ DON'T +- Use `apt-get` commands (Alpine doesn't have apt) +- Install packages without `--no-cache` flag +- Hardcode Alpine-specific paths +- Mix Alpine and Debian commands +- Forget to enable services with `rc-update` +- Use `systemctl` (Alpine has OpenRC, not systemd) + +## Alpine Repository Configuration + +### Default Repositories +Alpine comes with main repository enabled by default. Additional repos: + +```bash +# Community repository (apk add php, go, rust, etc.) +add_community_repo + +# Testing repository (bleeding edge packages) +add_testing_repo +``` + +### Repository Locations +```bash +/etc/apk/repositories # Main repo list +/etc/apk/keys/ # GPG keys for repos +/var/cache/apk/ # Package cache +``` + +## Package Size Optimization + +Alpine is designed for small container images: + +```bash +# DON'T: Leaves package cache (increases image size) +apk add nginx + +# DO: Remove cache to reduce size +apk add --no-cache nginx + +# Expected sizes: +# Alpine base: ~5MB +# Alpine + nginx: ~10-15MB +# Debian base: ~75MB +# Debian + nginx: ~90-95MB +``` + +## Service Management on Alpine + +### Using OpenRC +```bash +# Start service immediately +rc-service nginx start + +# Stop service +rc-service nginx stop + +# Restart service +rc-service nginx restart + +# Enable at boot +rc-update add nginx + +# Disable at boot +rc-update del nginx + +# List enabled services +rc-update show +``` + +## Troubleshooting + +### "apk: lock is held by PID" +```bash +# Alpine apk database is locked (another process using apk) +# Wait a moment +sleep 5 +apk_update + +# Or manually: +rm /var/lib/apk/lock 2>/dev/null || true +apk update +``` + +### "Package not found" +```bash +# May be in community or testing repository +add_community_repo +apk_update +apk_add package-name +``` + +### "Repository not responding" +```bash +# Alpine repo may be slow or unreachable +# Try updating again with retry logic +apk_update # Built-in retry logic + +# Or manually retry +sleep 10 +apk update +``` + +### "Service fails to start" +```bash +# Check service status on Alpine +rc-service nginx status + +# View logs +tail /var/log/nginx/error.log + +# Verify configuration +nginx -t +``` + +## Related Documentation + +- **[alpine-install.func/](../alpine-install.func/)** - Alpine installation functions +- **[tools.func/](../tools.func/)** - Debian/standard tool installation +- **[core.func/](../core.func/)** - Utility functions +- **[error_handler.func/](../error_handler.func/)** - Error handling +- **[UPDATED_APP-install.md](../../UPDATED_APP-install.md)** - Application script guide + +## Recent Updates + +### Version 2.0 (Dec 2025) +- βœ… Enhanced apk error handling and retry logic +- βœ… Improved repository management +- βœ… Better service management with OpenRC +- βœ… Added Alpine-specific optimization guidance +- βœ… Enhanced package cache management + +--- + +**Last Updated**: December 2025 +**Maintainers**: community-scripts team +**License**: MIT diff --git a/docs/misc/api.func/API_FLOWCHART.md b/docs/misc/api.func/API_FLOWCHART.md new file mode 100644 index 000000000..a46cd56e9 --- /dev/null +++ b/docs/misc/api.func/API_FLOWCHART.md @@ -0,0 +1,342 @@ +# api.func Execution Flowchart + +## Main API Communication Flow + +``` +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ API Communication Initialization β”‚ +β”‚ Entry point when api.func functions are called by installation scripts β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ 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 β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ 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 β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ 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 β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +``` + +## LXC API Reporting Flow + +``` +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ POST_TO_API() Flow β”‚ +β”‚ Send LXC container installation data to API β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ 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 β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ 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 β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ 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 β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +``` + +## Error Description Flow + +``` +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ GET_ERROR_DESCRIPTION() Flow β”‚ +β”‚ Convert numeric exit codes to human-readable explanations β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ 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 β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ 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 β”‚ β”‚ +β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +``` + +## 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 + +### With Error Handling +- **error_handler.func**: Provides error explanations +- **core.func**: Uses error descriptions in silent execution +- **Diagnostic reporting**: Tracks error patterns + +### External Dependencies +- **curl**: HTTP client for API communication +- **Community Scripts API**: External API endpoint +- **Network connectivity**: Required for API communication diff --git a/docs/misc/api.func/API_FUNCTIONS_REFERENCE.md b/docs/misc/api.func/API_FUNCTIONS_REFERENCE.md new file mode 100644 index 000000000..732261f49 --- /dev/null +++ b/docs/misc/api.func/API_FUNCTIONS_REFERENCE.md @@ -0,0 +1,433 @@ +# api.func Functions Reference + +## Overview + +This document provides a comprehensive alphabetical reference of all functions in `api.func`, including parameters, dependencies, usage examples, and error handling. + +## Function Categories + +### Error Description Functions + +#### `get_error_description()` +**Purpose**: Convert numeric exit codes to human-readable explanations +**Parameters**: +- `$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 + +**Usage Example**: +```bash +error_msg=$(get_error_description 127) +echo "Error 127: $error_msg" +# Output: Error 127: Command not found: Incorrect path or missing dependency. +``` + +**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." +``` + +### API Communication Functions + +#### `post_to_api()` +**Purpose**: Send LXC container installation data to community-scripts.org API +**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 +**Dependencies**: `curl` command +**Environment Variables Used**: `DIAGNOSTICS`, `RANDOM_UUID`, `CT_TYPE`, `DISK_SIZE`, `CORE_COUNT`, `RAM_SIZE`, `var_os`, `var_version`, `DISABLEIP6`, `NSAPP`, `METHOD` + +**Prerequisites**: +- `curl` command must be available +- `DIAGNOSTICS` must be set to "yes" +- `RANDOM_UUID` must be set and not empty + +**API Endpoint**: `http://api.community-scripts.org/dev/upload` + +**JSON Payload Structure**: +```json +{ + "ct_type": 1, + "type": "lxc", + "disk_size": 8, + "core_count": 2, + "ram_size": 2048, + "os_type": "debian", + "os_version": "12", + "disableip6": "true", + "nsapp": "plex", + "method": "install", + "pve_version": "8.0", + "status": "installing", + "random_id": "uuid-string" +} +``` + +**Usage Example**: +```bash +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 NSAPP="plex" +export METHOD="install" + +post_to_api +``` + +#### `post_to_api_vm()` +**Purpose**: Send VM installation data to community-scripts.org API +**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 +**Dependencies**: `curl` command, diagnostics file +**Environment Variables Used**: `DIAGNOSTICS`, `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 +- `RANDOM_UUID` must be set and not empty + +**API Endpoint**: `http://api.community-scripts.org/dev/upload` + +**JSON Payload Structure**: +```json +{ + "ct_type": 2, + "type": "vm", + "disk_size": 8, + "core_count": 2, + "ram_size": 2048, + "os_type": "debian", + "os_version": "12", + "disableip6": "", + "nsapp": "plex", + "method": "install", + "pve_version": "8.0", + "status": "installing", + "random_id": "uuid-string" +} +``` + +**Usage Example**: +```bash +# Create diagnostics file +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 METHOD="install" + +post_to_api_vm +``` + +#### `post_update_to_api()` +**Purpose**: Send installation completion status to community-scripts.org API +**Parameters**: +- `$1` - Status ("success" or "failed", default: "failed") +- `$2` - Exit code (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` + +**Prerequisites**: +- `curl` command must be available +- `DIAGNOSTICS` must be set to "yes" +- `RANDOM_UUID` must be set and not empty +- POST_UPDATE_DONE must be false (prevents duplicates) + +**API Endpoint**: `http://api.community-scripts.org/dev/upload/updatestatus` + +**JSON Payload Structure**: +```json +{ + "status": "success", + "error": "Error description from get_error_description()", + "random_id": "uuid-string" +} +``` + +**Usage Example**: +```bash +export DIAGNOSTICS="yes" +export RANDOM_UUID="$(uuidgen)" + +# Report successful installation +post_update_to_api "success" 0 + +# Report failed installation +post_update_to_api "failed" 127 +``` + +## Function Call Hierarchy + +### API Communication Flow +``` +post_to_api() +β”œβ”€β”€ Check curl availability +β”œβ”€β”€ Check DIAGNOSTICS setting +β”œβ”€β”€ Check RANDOM_UUID +β”œβ”€β”€ Get PVE version +β”œβ”€β”€ Create JSON payload +└── Send HTTP POST request + +post_to_api_vm() +β”œβ”€β”€ Check diagnostics file +β”œβ”€β”€ Check curl availability +β”œβ”€β”€ Check DIAGNOSTICS setting +β”œβ”€β”€ Check RANDOM_UUID +β”œβ”€β”€ Process disk size +β”œβ”€β”€ Get PVE version +β”œβ”€β”€ Create JSON payload +└── Send HTTP POST request + +post_update_to_api() +β”œβ”€β”€ Check POST_UPDATE_DONE flag +β”œβ”€β”€ Check curl availability +β”œβ”€β”€ Check DIAGNOSTICS setting +β”œβ”€β”€ Check RANDOM_UUID +β”œβ”€β”€ Determine status and exit code +β”œβ”€β”€ Get error description +β”œβ”€β”€ Create JSON payload +β”œβ”€β”€ Send HTTP POST request +└── Set POST_UPDATE_DONE=true +``` + +### Error Description Flow +``` +get_error_description() +β”œβ”€β”€ Match exit code +β”œβ”€β”€ Return appropriate description +└── Handle unknown codes +``` + +## Error Code Reference + +### General System Errors +| 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. | + +### Command Execution Errors +| 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. | + +### Signal Errors +| 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. | + +### LXC-Specific Errors +| 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. | + +### Other Errors +| Code | Description | +|------|-------------| +| 255 | Unknown critical error, often due to missing permissions or broken scripts. | +| * | Unknown error code (exit_code). | + +## Environment Variable Dependencies + +### Required Variables +- **`DIAGNOSTICS`**: Enable/disable diagnostic reporting ("yes"/"no") +- **`RANDOM_UUID`**: Unique identifier for 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) +- **`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 + +### 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 + +## 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 + +### 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 + +## Integration Examples + +### With build.func +```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 +post_to_api + +# Container creation... +# ... build.func code ... + +# Report completion +if [[ $? -eq 0 ]]; then + post_update_to_api "success" 0 +else + post_update_to_api "failed" $? +fi +``` + +### With vm-core.func +```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 +post_to_api_vm + +# VM creation... +# ... vm-core.func code ... + +# Report completion +post_update_to_api "success" 0 +``` + +### With error_handler.func +```bash +#!/usr/bin/env bash +source core.func +source error_handler.func +source api.func + +# Use error descriptions +error_code=127 +error_msg=$(get_error_description $error_code) +echo "Error $error_code: $error_msg" + +# Report error to API +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 + +### Error Reporting +1. Use appropriate error codes +2. Provide meaningful error descriptions +3. Report both success and failure cases +4. Prevent duplicate status 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 diff --git a/docs/misc/api.func/API_INTEGRATION.md b/docs/misc/api.func/API_INTEGRATION.md new file mode 100644 index 000000000..f325dace2 --- /dev/null +++ b/docs/misc/api.func/API_INTEGRATION.md @@ -0,0 +1,643 @@ +# api.func Integration Guide + +## Overview + +This document describes how `api.func` integrates with other components in the Proxmox Community Scripts project, including dependencies, data flow, and API surface. + +## Dependencies + +### External Dependencies + +#### Required Commands +- **`curl`**: HTTP client for API communication +- **`uuidgen`**: Generate unique identifiers (optional, can use other methods) + +#### Optional Commands +- **None**: No other external command dependencies + +### Internal Dependencies + +#### Environment Variables from Other Scripts +- **build.func**: Provides container creation variables +- **vm-core.func**: Provides VM creation variables +- **core.func**: Provides system information variables +- **Installation scripts**: Provide application-specific variables + +## Integration Points + +### With build.func + +#### 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" + + # Report installation start + post_to_api + + # Container creation using build.func + # ... build.func container creation logic ... + + # Report completion + if [[ $? -eq 0 ]]; then + post_update_to_api "success" 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) + + echo "Container creation failed: $error_msg" + post_update_to_api "failed" $exit_code +} +``` + +### With vm-core.func + +#### 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 +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" + + # Report VM installation start + post_to_api_vm + + # VM creation using vm-core.func + # ... vm-core.func VM creation logic ... + + # 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 +} +``` + +### 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) + + # 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 +} +``` + +### With install.func + +#### 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_to_api + + # Package installation using install.func + if install_package "$package"; then + echo "$package installed successfully" + post_update_to_api "success" 0 + return 0 + else + local exit_code=$? + local error_msg=$(get_error_description $exit_code) + echo "$package installation failed: $error_msg" + post_update_to_api "failed" $exit_code + return $exit_code + fi +} +``` + +### 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 + +#### 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 + +#### 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 + +### Processing Data + +#### 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 + +#### 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 + +### 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 + +#### 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 + +## 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 + +#### 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 + +### Internal Functions + +#### None +- All functions in api.func are public +- No internal helper functions +- Direct implementation of all functionality + +### Global Variables + +#### 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 + +## Integration Patterns + +### Standard Integration Pattern + +```bash +#!/usr/bin/env bash +# Standard integration pattern + +# 1. Source core.func first +source core.func + +# 2. Source api.func +source api.func + +# 3. Set up API reporting +export DIAGNOSTICS="yes" +export RANDOM_UUID="$(uuidgen)" + +# 4. Set application parameters +export NSAPP="$APP" +export METHOD="install" + +# 5. Report installation start +post_to_api + +# 6. Perform installation +# ... installation logic ... + +# 7. Report completion +post_update_to_api "success" 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 +post_update_to_api "failed" 127 +``` + +### Advanced Integration Pattern + +```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 +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 handling with API reporting +enhanced_error_handler() { + local exit_code=${1:-$?} + local command=${2:-${BASH_COMMAND:-unknown}} + + local error_msg=$(get_error_description $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 + +# Advanced operations with API reporting +post_to_api +# ... operations ... +post_update_to_api "success" 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 + +### 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 + +## 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 + +### 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 diff --git a/docs/misc/api.func/API_USAGE_EXAMPLES.md b/docs/misc/api.func/API_USAGE_EXAMPLES.md new file mode 100644 index 000000000..616ebc927 --- /dev/null +++ b/docs/misc/api.func/API_USAGE_EXAMPLES.md @@ -0,0 +1,794 @@ +# 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" +``` diff --git a/docs/misc/api.func/README.md b/docs/misc/api.func/README.md new file mode 100644 index 000000000..6cf90d23d --- /dev/null +++ b/docs/misc/api.func/README.md @@ -0,0 +1,199 @@ +# api.func Documentation + +## 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. + +## Purpose and Use Cases + +- **API Communication**: Send installation and status data to community-scripts.org API +- **Diagnostic Reporting**: Report installation progress and errors for analytics +- **Error Description**: Provide detailed error code explanations +- **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 + +### Dependencies +- **External**: `curl` command for HTTP requests +- **Internal**: Uses environment variables from other scripts + +### 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 + +## Documentation Files + +### πŸ“Š [API_FLOWCHART.md](./API_FLOWCHART.md) +Visual execution flows showing API communication processes and error handling. + +### πŸ“š [API_FUNCTIONS_REFERENCE.md](./API_FUNCTIONS_REFERENCE.md) +Complete alphabetical reference of all functions with parameters, dependencies, and usage details. + +### πŸ’‘ [API_USAGE_EXAMPLES.md](./API_USAGE_EXAMPLES.md) +Practical examples showing how to use API functions and common patterns. + +### πŸ”— [API_INTEGRATION.md](./API_INTEGRATION.md) +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 +- **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 + +### Diagnostic Integration +- **Optional Reporting**: Only sends data when diagnostics enabled +- **Privacy Respect**: Respects user privacy settings +- **Error Tracking**: Tracks installation errors for improvement +- **Usage Analytics**: Contributes to project statistics + +## Common Usage Patterns + +### 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)" + +# Report installation start +post_to_api +``` + +### Error Reporting +```bash +#!/usr/bin/env bash +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. +``` + +### Status Updates +```bash +#!/usr/bin/env bash +source api.func + +# Report successful installation +post_update_to_api "success" 0 + +# Report failed installation +post_update_to_api "failed" 127 +``` + +## Environment Variables + +### Required Variables +- `DIAGNOSTICS`: Enable/disable diagnostic reporting ("yes"/"no") +- `RANDOM_UUID`: Unique identifier for tracking + +### Optional Variables +- `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 + +### Internal Variables +- `POST_UPDATE_DONE`: Prevents duplicate status updates +- `API_URL`: Community scripts API endpoint +- `JSON_PAYLOAD`: API request payload +- `RESPONSE`: API response + +## Error Code Categories + +### 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 + +## Best Practices + +### Diagnostic Reporting +1. Always check if diagnostics are enabled +2. Respect user privacy settings +3. Use unique identifiers for tracking +4. Report both success and failure cases + +### Error Handling +1. Use appropriate error codes +2. Provide meaningful error descriptions +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 + +## 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 + +### Debug Mode +Enable diagnostic reporting for debugging: +```bash +export DIAGNOSTICS="yes" +export RANDOM_UUID="$(uuidgen)" +``` + +### API Testing +Test API communication: +```bash +source api.func +export DIAGNOSTICS="yes" +export RANDOM_UUID="test-$(date +%s)" +post_to_api +``` + +## Related Documentation + +- [core.func](../core.func/) - Core utilities and error handling +- [error_handler.func](../error_handler.func/) - Error handling utilities +- [build.func](../build.func/) - Container creation with API integration +- [tools.func](../tools.func/) - Extended utilities with API integration + +--- + +*This documentation covers the api.func file which provides API communication and diagnostic reporting for all Proxmox Community Scripts.* diff --git a/docs/misc/build.func/BUILD_FUNC_ARCHITECTURE.md b/docs/misc/build.func/BUILD_FUNC_ARCHITECTURE.md new file mode 100644 index 000000000..1d9c5ed22 --- /dev/null +++ b/docs/misc/build.func/BUILD_FUNC_ARCHITECTURE.md @@ -0,0 +1,410 @@ +# build.func Architecture Guide + +## Overview + +This document provides a high-level architectural overview of `build.func`, including module dependencies, data flow, integration points, and system architecture. + +## High-Level Architecture + +``` +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ Proxmox Host System β”‚ +β”‚ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ build.func β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ +β”‚ β”‚ β”‚ Entry Point β”‚ β”‚ Configuration β”‚ β”‚ Container Creation β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ start() β”‚ β”‚ β€’ variables() β”‚ β”‚ β€’ build_container() β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ install_ β”‚ β”‚ β€’ base_ β”‚ β”‚ β€’ create_lxc_container() β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ script() β”‚ β”‚ settings() β”‚ β”‚ β€’ configure_gpu_ β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ advanced_ β”‚ β”‚ β€’ select_ β”‚ β”‚ passthrough() β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ settings() β”‚ β”‚ storage() β”‚ β”‚ β€’ fix_gpu_gids() β”‚ β”‚ β”‚ +β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β”‚ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ Module Dependencies β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ +β”‚ β”‚ β”‚ core.func β”‚ β”‚ error_handler. β”‚ β”‚ api.func β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ func β”‚ β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ Basic β”‚ β”‚ β€’ Error β”‚ β”‚ β€’ Proxmox API β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ utilities β”‚ β”‚ handling β”‚ β”‚ interactions β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ Common β”‚ β”‚ β€’ Error β”‚ β”‚ β€’ Container β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ functions β”‚ β”‚ recovery β”‚ β”‚ management β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ System β”‚ β”‚ β€’ Cleanup β”‚ β”‚ β€’ Status β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ utilities β”‚ β”‚ functions β”‚ β”‚ monitoring β”‚ β”‚ β”‚ +β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ +β”‚ β”‚ β”‚ tools.func β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ Additional utilities β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ Helper functions β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ System tools β”‚ β”‚ β”‚ +β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +``` + +## Module Dependencies + +### Core Dependencies + +``` +build.func Dependencies: +β”œβ”€β”€ core.func +β”‚ β”œβ”€β”€ Basic system utilities +β”‚ β”œβ”€β”€ Common functions +β”‚ β”œβ”€β”€ System information +β”‚ └── File operations +β”œβ”€β”€ error_handler.func +β”‚ β”œβ”€β”€ Error handling +β”‚ β”œβ”€β”€ Error recovery +β”‚ β”œβ”€β”€ Cleanup functions +β”‚ └── Error logging +β”œβ”€β”€ api.func +β”‚ β”œβ”€β”€ Proxmox API interactions +β”‚ β”œβ”€β”€ Container management +β”‚ β”œβ”€β”€ Status monitoring +β”‚ └── Configuration updates +└── tools.func + β”œβ”€β”€ Additional utilities + β”œβ”€β”€ Helper functions + β”œβ”€β”€ System tools + └── Custom functions +``` + +### Dependency Flow + +``` +Dependency Flow: +β”œβ”€β”€ build.func +β”‚ β”œβ”€β”€ Sources core.func +β”‚ β”œβ”€β”€ Sources error_handler.func +β”‚ β”œβ”€β”€ Sources api.func +β”‚ └── Sources tools.func +β”œβ”€β”€ core.func +β”‚ β”œβ”€β”€ Basic utilities +β”‚ └── System functions +β”œβ”€β”€ error_handler.func +β”‚ β”œβ”€β”€ Error management +β”‚ └── Recovery functions +β”œβ”€β”€ api.func +β”‚ β”œβ”€β”€ Proxmox integration +β”‚ └── Container operations +└── tools.func + β”œβ”€β”€ Additional tools + └── Helper functions +``` + +## Data Flow Architecture + +### Configuration Data Flow + +``` +Configuration Data Flow: +β”œβ”€β”€ Environment Variables +β”‚ β”œβ”€β”€ Hard environment variables +β”‚ β”œβ”€β”€ App-specific .vars +β”‚ β”œβ”€β”€ Global default.vars +β”‚ └── Built-in defaults +β”œβ”€β”€ Variable Resolution +β”‚ β”œβ”€β”€ Apply precedence chain +β”‚ β”œβ”€β”€ Validate settings +β”‚ └── Resolve conflicts +β”œβ”€β”€ Configuration Storage +β”‚ β”œβ”€β”€ Memory variables +β”‚ β”œβ”€β”€ Temporary files +β”‚ └── Persistent storage +└── Configuration Usage + β”œβ”€β”€ Container creation + β”œβ”€β”€ Feature configuration + └── Settings persistence +``` + +### Container Data Flow + +``` +Container Data Flow: +β”œβ”€β”€ Input Data +β”‚ β”œβ”€β”€ Configuration variables +β”‚ β”œβ”€β”€ Resource specifications +β”‚ β”œβ”€β”€ Network settings +β”‚ └── Storage requirements +β”œβ”€β”€ Processing +β”‚ β”œβ”€β”€ Validation +β”‚ β”œβ”€β”€ Conflict resolution +β”‚ β”œβ”€β”€ Resource allocation +β”‚ └── Configuration generation +β”œβ”€β”€ Container Creation +β”‚ β”œβ”€β”€ LXC container creation +β”‚ β”œβ”€β”€ Network configuration +β”‚ β”œβ”€β”€ Storage setup +β”‚ └── Feature configuration +└── Output + β”œβ”€β”€ Container status + β”œβ”€β”€ Access information + β”œβ”€β”€ Configuration files + └── Log files +``` + +## Integration Architecture + +### With Proxmox System + +``` +Proxmox Integration: +β”œβ”€β”€ Proxmox Host +β”‚ β”œβ”€β”€ LXC container management +β”‚ β”œβ”€β”€ Storage management +β”‚ β”œβ”€β”€ Network management +β”‚ └── Resource management +β”œβ”€β”€ Proxmox API +β”‚ β”œβ”€β”€ Container operations +β”‚ β”œβ”€β”€ Configuration updates +β”‚ β”œβ”€β”€ Status monitoring +β”‚ └── Error handling +β”œβ”€β”€ Proxmox Configuration +β”‚ β”œβ”€β”€ /etc/pve/lxc/.conf +β”‚ β”œβ”€β”€ Storage configuration +β”‚ β”œβ”€β”€ Network configuration +β”‚ └── Resource configuration +└── Proxmox Services + β”œβ”€β”€ Container services + β”œβ”€β”€ Network services + β”œβ”€β”€ Storage services + └── Monitoring services +``` + +### With Install Scripts + +``` +Install Script Integration: +β”œβ”€β”€ build.func +β”‚ β”œβ”€β”€ Creates container +β”‚ β”œβ”€β”€ Configures basic settings +β”‚ β”œβ”€β”€ Starts container +β”‚ └── Provides access +β”œβ”€β”€ Install Scripts +β”‚ β”œβ”€β”€ -install.sh +β”‚ β”œβ”€β”€ Downloads application +β”‚ β”œβ”€β”€ Configures application +β”‚ └── Sets up services +β”œβ”€β”€ Container +β”‚ β”œβ”€β”€ Running application +β”‚ β”œβ”€β”€ Configured services +β”‚ β”œβ”€β”€ Network access +β”‚ └── Storage access +└── Integration Points + β”œβ”€β”€ Container creation + β”œβ”€β”€ Network configuration + β”œβ”€β”€ Storage setup + └── Service configuration +``` + +## System Architecture Components + +### Core Components + +``` +System Components: +β”œβ”€β”€ Entry Point +β”‚ β”œβ”€β”€ start() function +β”‚ β”œβ”€β”€ Context detection +β”‚ β”œβ”€β”€ Environment capture +β”‚ └── Workflow routing +β”œβ”€β”€ Configuration Management +β”‚ β”œβ”€β”€ Variable resolution +β”‚ β”œβ”€β”€ Settings persistence +β”‚ β”œβ”€β”€ Default management +β”‚ └── Validation +β”œβ”€β”€ Container Creation +β”‚ β”œβ”€β”€ LXC container creation +β”‚ β”œβ”€β”€ Network configuration +β”‚ β”œβ”€β”€ Storage setup +β”‚ └── Feature configuration +β”œβ”€β”€ Hardware Integration +β”‚ β”œβ”€β”€ GPU passthrough +β”‚ β”œβ”€β”€ USB passthrough +β”‚ β”œβ”€β”€ Storage management +β”‚ └── Network management +└── Error Handling + β”œβ”€β”€ Error detection + β”œβ”€β”€ Error recovery + β”œβ”€β”€ Cleanup functions + └── User notification +``` + +### User Interface Components + +``` +UI Components: +β”œβ”€β”€ Menu System +β”‚ β”œβ”€β”€ Installation mode selection +β”‚ β”œβ”€β”€ Configuration menus +β”‚ β”œβ”€β”€ Storage selection +β”‚ └── GPU configuration +β”œβ”€β”€ Interactive Elements +β”‚ β”œβ”€β”€ Whiptail menus +β”‚ β”œβ”€β”€ User prompts +β”‚ β”œβ”€β”€ Confirmation dialogs +β”‚ └── Error messages +β”œβ”€β”€ Non-Interactive Mode +β”‚ β”œβ”€β”€ Environment variable driven +β”‚ β”œβ”€β”€ Silent execution +β”‚ β”œβ”€β”€ Automated configuration +β”‚ └── Error handling +└── Output + β”œβ”€β”€ Status messages + β”œβ”€β”€ Progress indicators + β”œβ”€β”€ Completion information + └── Access details +``` + +## Security Architecture + +### Security Considerations + +``` +Security Architecture: +β”œβ”€β”€ Container Security +β”‚ β”œβ”€β”€ Unprivileged containers (default) +β”‚ β”œβ”€β”€ Privileged containers (when needed) +β”‚ β”œβ”€β”€ Resource limits +β”‚ └── Access controls +β”œβ”€β”€ Network Security +β”‚ β”œβ”€β”€ Network isolation +β”‚ β”œβ”€β”€ VLAN support +β”‚ β”œβ”€β”€ Firewall integration +β”‚ └── Access controls +β”œβ”€β”€ Storage Security +β”‚ β”œβ”€β”€ Storage isolation +β”‚ β”œβ”€β”€ Access controls +β”‚ β”œβ”€β”€ Encryption support +β”‚ └── Backup integration +β”œβ”€β”€ GPU Security +β”‚ β”œβ”€β”€ Device isolation +β”‚ β”œβ”€β”€ Permission management +β”‚ β”œβ”€β”€ Access controls +β”‚ └── Security validation +└── API Security + β”œβ”€β”€ Authentication + β”œβ”€β”€ Authorization + β”œβ”€β”€ Input validation + └── Error handling +``` + +## Performance Architecture + +### Performance Considerations + +``` +Performance Architecture: +β”œβ”€β”€ Execution Optimization +β”‚ β”œβ”€β”€ Parallel operations +β”‚ β”œβ”€β”€ Efficient algorithms +β”‚ β”œβ”€β”€ Minimal user interaction +β”‚ └── Optimized validation +β”œβ”€β”€ Resource Management +β”‚ β”œβ”€β”€ Memory efficiency +β”‚ β”œβ”€β”€ CPU optimization +β”‚ β”œβ”€β”€ Disk usage optimization +β”‚ └── Network efficiency +β”œβ”€β”€ Caching +β”‚ β”œβ”€β”€ Configuration caching +β”‚ β”œβ”€β”€ Template caching +β”‚ β”œβ”€β”€ Storage caching +β”‚ └── GPU detection caching +└── Monitoring + β”œβ”€β”€ Performance monitoring + β”œβ”€β”€ Resource monitoring + β”œβ”€β”€ Error monitoring + └── Status monitoring +``` + +## Deployment Architecture + +### Deployment Scenarios + +``` +Deployment Scenarios: +β”œβ”€β”€ Single Container +β”‚ β”œβ”€β”€ Individual application +β”‚ β”œβ”€β”€ Standard configuration +β”‚ β”œβ”€β”€ Basic networking +β”‚ └── Standard storage +β”œβ”€β”€ Multiple Containers +β”‚ β”œβ”€β”€ Application stack +β”‚ β”œβ”€β”€ Shared networking +β”‚ β”œβ”€β”€ Shared storage +β”‚ └── Coordinated deployment +β”œβ”€β”€ High Availability +β”‚ β”œβ”€β”€ Redundant containers +β”‚ β”œβ”€β”€ Load balancing +β”‚ β”œβ”€β”€ Failover support +β”‚ └── Monitoring integration +└── Development Environment + β”œβ”€β”€ Development containers + β”œβ”€β”€ Testing containers + β”œβ”€β”€ Staging containers + └── Production containers +``` + +## Maintenance Architecture + +### Maintenance Components + +``` +Maintenance Architecture: +β”œβ”€β”€ Updates +β”‚ β”œβ”€β”€ Container updates +β”‚ β”œβ”€β”€ Application updates +β”‚ β”œβ”€β”€ Configuration updates +β”‚ └── Security updates +β”œβ”€β”€ Monitoring +β”‚ β”œβ”€β”€ Container monitoring +β”‚ β”œβ”€β”€ Resource monitoring +β”‚ β”œβ”€β”€ Performance monitoring +β”‚ └── Error monitoring +β”œβ”€β”€ Backup +β”‚ β”œβ”€β”€ Configuration backup +β”‚ β”œβ”€β”€ Container backup +β”‚ β”œβ”€β”€ Storage backup +β”‚ └── Recovery procedures +└── Troubleshooting + β”œβ”€β”€ Error diagnosis + β”œβ”€β”€ Log analysis + β”œβ”€β”€ Performance analysis + └── Recovery procedures +``` + +## Future Architecture Considerations + +### Scalability + +``` +Scalability Considerations: +β”œβ”€β”€ Horizontal Scaling +β”‚ β”œβ”€β”€ Multiple containers +β”‚ β”œβ”€β”€ Load balancing +β”‚ β”œβ”€β”€ Distributed deployment +β”‚ └── Resource distribution +β”œβ”€β”€ Vertical Scaling +β”‚ β”œβ”€β”€ Resource scaling +β”‚ β”œβ”€β”€ Performance optimization +β”‚ β”œβ”€β”€ Capacity planning +β”‚ └── Resource management +β”œβ”€β”€ Automation +β”‚ β”œβ”€β”€ Automated deployment +β”‚ β”œβ”€β”€ Automated scaling +β”‚ β”œβ”€β”€ Automated monitoring +β”‚ └── Automated recovery +└── Integration + β”œβ”€β”€ External systems + β”œβ”€β”€ Cloud integration + β”œβ”€β”€ Container orchestration + └── Service mesh +``` diff --git a/docs/misc/build.func/BUILD_FUNC_ENVIRONMENT_VARIABLES.md b/docs/misc/build.func/BUILD_FUNC_ENVIRONMENT_VARIABLES.md new file mode 100644 index 000000000..b116d3106 --- /dev/null +++ b/docs/misc/build.func/BUILD_FUNC_ENVIRONMENT_VARIABLES.md @@ -0,0 +1,248 @@ +# build.func Environment Variables Reference + +## Overview + +This document provides a comprehensive reference of all environment variables used in `build.func`, organized by category and usage context. + +## Variable Categories + +### Core Container Variables + +| Variable | Description | Default | Set In | Used In | +|----------|-------------|---------|---------|---------| +| `APP` | Application name (e.g., "plex", "nextcloud") | - | Environment | Throughout | +| `NSAPP` | Namespace application name | `$APP` | Environment | Throughout | +| `CTID` | Container ID | - | Environment | Container creation | +| `CT_TYPE` | Container type ("install" or "update") | "install" | Environment | Entry point | +| `CT_NAME` | Container name | `$APP` | Environment | Container creation | + +### Operating System Variables + +| Variable | Description | Default | Set In | Used In | +|----------|-------------|---------|---------|---------| +| `var_os` | Operating system selection | "debian" | base_settings() | OS selection | +| `var_version` | OS version | "12" | base_settings() | Template selection | +| `var_template` | Template name | Auto-generated | base_settings() | Template download | + +### Resource Configuration Variables + +| Variable | Description | Default | Set In | Used In | +|----------|-------------|---------|---------|---------| +| `var_cpu` | CPU cores | "2" | base_settings() | Container creation | +| `var_ram` | RAM in MB | "2048" | base_settings() | Container creation | +| `var_disk` | Disk size in GB | "8" | base_settings() | Container creation | +| `DISK_SIZE` | Disk size (alternative) | `$var_disk` | Environment | Container creation | +| `CORE_COUNT` | CPU cores (alternative) | `$var_cpu` | Environment | Container creation | +| `RAM_SIZE` | RAM size (alternative) | `$var_ram` | Environment | Container creation | + +### Network Configuration Variables + +| Variable | Description | Default | Set In | Used In | +|----------|-------------|---------|---------|---------| +| `var_net` | Network interface | "vmbr0" | base_settings() | Network config | +| `var_bridge` | Bridge interface | "vmbr0" | base_settings() | Network config | +| `var_gateway` | Gateway IP | "192.168.1.1" | base_settings() | Network config | +| `var_ip` | Container IP address | - | User input | Network config | +| `var_ipv6` | IPv6 address | - | User input | Network config | +| `var_vlan` | VLAN ID | - | User input | Network config | +| `var_mtu` | MTU size | "1500" | base_settings() | Network config | +| `var_mac` | MAC address | Auto-generated | base_settings() | Network config | +| `NET` | Network interface (alternative) | `$var_net` | Environment | Network config | +| `BRG` | Bridge interface (alternative) | `$var_bridge` | Environment | Network config | +| `GATE` | Gateway IP (alternative) | `$var_gateway` | Environment | Network config | +| `IPV6_METHOD` | IPv6 configuration method | "none" | Environment | Network config | +| `VLAN` | VLAN ID (alternative) | `$var_vlan` | Environment | Network config | +| `MTU` | MTU size (alternative) | `$var_mtu` | Environment | Network config | +| `MAC` | MAC address (alternative) | `$var_mac` | Environment | Network config | + +### Storage Configuration Variables + +| Variable | Description | Default | Set In | Used In | +|----------|-------------|---------|---------|---------| +| `var_template_storage` | Storage for templates | - | select_storage() | Template storage | +| `var_container_storage` | Storage for container disks | - | select_storage() | Container storage | +| `TEMPLATE_STORAGE` | Template storage (alternative) | `$var_template_storage` | Environment | Template storage | +| `CONTAINER_STORAGE` | Container storage (alternative) | `$var_container_storage` | Environment | Container storage | + +### Feature Flags + +| Variable | Description | Default | Set In | Used In | +|----------|-------------|---------|---------|---------| +| `ENABLE_FUSE` | Enable FUSE support | "true" | base_settings() | Container features | +| `ENABLE_TUN` | Enable TUN/TAP support | "true" | base_settings() | Container features | +| `ENABLE_KEYCTL` | Enable keyctl support | "true" | base_settings() | Container features | +| `ENABLE_MOUNT` | Enable mount support | "true" | base_settings() | Container features | +| `ENABLE_NESTING` | Enable nesting support | "false" | base_settings() | Container features | +| `ENABLE_PRIVILEGED` | Enable privileged mode | "false" | base_settings() | Container features | +| `ENABLE_UNPRIVILEGED` | Enable unprivileged mode | "true" | base_settings() | Container features | +| `VERBOSE` | Enable verbose output | "false" | Environment | Logging | +| `SSH` | Enable SSH key provisioning | "true" | base_settings() | SSH setup | + +### GPU Passthrough Variables + +| Variable | Description | Default | Set In | Used In | +|----------|-------------|---------|---------|---------| +| `GPU_APPS` | List of apps that support GPU | - | Environment | GPU detection | +| `var_gpu` | GPU selection | - | User input | GPU passthrough | +| `var_gpu_type` | GPU type (intel/amd/nvidia) | - | detect_gpu_devices() | GPU passthrough | +| `var_gpu_devices` | GPU device list | - | detect_gpu_devices() | GPU passthrough | + +### API and Diagnostics Variables + +| Variable | Description | Default | Set In | Used In | +|----------|-------------|---------|---------|---------| +| `DIAGNOSTICS` | Enable diagnostics mode | "false" | Environment | Diagnostics | +| `METHOD` | Installation method | "install" | Environment | Installation flow | +| `RANDOM_UUID` | Random UUID for tracking | - | Environment | Logging | +| `API_TOKEN` | Proxmox API token | - | Environment | API calls | +| `API_USER` | Proxmox API user | - | Environment | API calls | + +### Settings Persistence Variables + +| Variable | Description | Default | Set In | Used In | +|----------|-------------|---------|---------|---------| +| `SAVE_DEFAULTS` | Save settings as defaults | "false" | User input | Settings persistence | +| `SAVE_APP_DEFAULTS` | Save app-specific defaults | "false" | User input | Settings persistence | +| `DEFAULT_VARS_FILE` | Path to default.vars | "/usr/local/community-scripts/default.vars" | Environment | Settings persistence | +| `APP_DEFAULTS_FILE` | Path to app.vars | "/usr/local/community-scripts/defaults/$APP.vars" | Environment | Settings persistence | + +## Variable Precedence Chain + +Variables are resolved in the following order (highest to lowest priority): + +1. **Hard Environment Variables**: Set before script execution +2. **App-specific .vars file**: `/usr/local/community-scripts/defaults/.vars` +3. **Global default.vars file**: `/usr/local/community-scripts/default.vars` +4. **Built-in defaults**: Set in `base_settings()` function + +## Critical Variables for Non-Interactive Use + +For silent/non-interactive execution, these variables must be set: + +```bash +# Core container settings +export APP="plex" +export CTID="100" +export var_hostname="plex-server" + +# OS selection +export var_os="debian" +export var_version="12" + +# Resource allocation +export var_cpu="4" +export var_ram="4096" +export var_disk="20" + +# Network configuration +export var_net="vmbr0" +export var_gateway="192.168.1.1" +export var_ip="192.168.1.100" + +# Storage selection +export var_template_storage="local" +export var_container_storage="local" + +# Feature flags +export ENABLE_FUSE="true" +export ENABLE_TUN="true" +export SSH="true" +``` + +## Environment Variable Usage Patterns + +### 1. Container Creation +```bash +# Basic container creation +export APP="nextcloud" +export CTID="101" +export var_hostname="nextcloud-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.101" +export var_template_storage="local" +export var_container_storage="local" +``` + +### 2. GPU Passthrough +```bash +# Enable GPU passthrough +export GPU_APPS="plex,jellyfin,emby" +export var_gpu="intel" +export ENABLE_PRIVILEGED="true" +``` + +### 3. Advanced Network Configuration +```bash +# VLAN and IPv6 configuration +export var_vlan="100" +export var_ipv6="2001:db8::100" +export IPV6_METHOD="static" +export var_mtu="9000" +``` + +### 4. Storage Configuration +```bash +# Custom storage locations +export var_template_storage="nfs-storage" +export var_container_storage="ssd-storage" +``` + +## Variable Validation + +The script validates variables at several points: + +1. **Container ID validation**: Must be unique and within valid range +2. **IP address validation**: Must be valid IPv4/IPv6 format +3. **Storage validation**: Must exist and support required content types +4. **Resource validation**: Must be within reasonable limits +5. **Network validation**: Must be valid network configuration + +## Common Variable Combinations + +### Development Container +```bash +export APP="dev-container" +export CTID="200" +export var_hostname="dev-server" +export var_os="ubuntu" +export var_version="22.04" +export var_cpu="4" +export var_ram="4096" +export var_disk="20" +export ENABLE_NESTING="true" +export ENABLE_PRIVILEGED="true" +``` + +### Media Server with GPU +```bash +export APP="plex" +export CTID="300" +export var_hostname="plex-server" +export var_os="debian" +export var_version="12" +export var_cpu="6" +export var_ram="8192" +export var_disk="50" +export GPU_APPS="plex" +export var_gpu="nvidia" +export ENABLE_PRIVILEGED="true" +``` + +### Lightweight Service +```bash +export APP="nginx" +export CTID="400" +export var_hostname="nginx-proxy" +export var_os="alpine" +export var_version="3.18" +export var_cpu="1" +export var_ram="512" +export var_disk="2" +export ENABLE_UNPRIVILEGED="true" +``` diff --git a/docs/misc/build.func/BUILD_FUNC_EXECUTION_FLOWS.md b/docs/misc/build.func/BUILD_FUNC_EXECUTION_FLOWS.md new file mode 100644 index 000000000..47a0035e2 --- /dev/null +++ b/docs/misc/build.func/BUILD_FUNC_EXECUTION_FLOWS.md @@ -0,0 +1,413 @@ +# build.func Execution Flows + +## Overview + +This document details the execution flows for different installation modes and scenarios in `build.func`, including variable precedence, decision trees, and workflow patterns. + +## Installation Modes + +### 1. Default Install Flow + +**Purpose**: Uses built-in defaults with minimal user interaction +**Use Case**: Quick container creation with standard settings + +``` +Default Install Flow: +β”œβ”€β”€ start() +β”‚ β”œβ”€β”€ Detect execution context +β”‚ β”œβ”€β”€ Capture hard environment variables +β”‚ └── Set CT_TYPE="install" +β”œβ”€β”€ install_script() +β”‚ β”œβ”€β”€ Display installation mode menu +β”‚ β”œβ”€β”€ User selects "Default Install" +β”‚ └── Proceed with defaults +β”œβ”€β”€ variables() +β”‚ β”œβ”€β”€ base_settings() # Set built-in defaults +β”‚ β”œβ”€β”€ Load app.vars (if exists) +β”‚ β”œβ”€β”€ Load default.vars (if exists) +β”‚ └── Apply variable precedence +β”œβ”€β”€ build_container() +β”‚ β”œβ”€β”€ validate_settings() +β”‚ β”œβ”€β”€ check_conflicts() +β”‚ └── create_lxc_container() +└── default_var_settings() + └── Offer to save as defaults +``` + +**Key Characteristics**: +- Minimal user prompts +- Uses built-in defaults +- Fast execution +- Suitable for standard deployments + +### 2. Advanced Install Flow + +**Purpose**: Full interactive configuration via whiptail menus +**Use Case**: Custom container configuration with full control + +``` +Advanced Install Flow: +β”œβ”€β”€ start() +β”‚ β”œβ”€β”€ Detect execution context +β”‚ β”œβ”€β”€ Capture hard environment variables +β”‚ └── Set CT_TYPE="install" +β”œβ”€β”€ install_script() +β”‚ β”œβ”€β”€ Display installation mode menu +β”‚ β”œβ”€β”€ User selects "Advanced Install" +β”‚ └── Proceed with advanced configuration +β”œβ”€β”€ variables() +β”‚ β”œβ”€β”€ base_settings() # Set built-in defaults +β”‚ β”œβ”€β”€ Load app.vars (if exists) +β”‚ β”œβ”€β”€ Load default.vars (if exists) +β”‚ └── Apply variable precedence +β”œβ”€β”€ advanced_settings() +β”‚ β”œβ”€β”€ OS Selection Menu +β”‚ β”œβ”€β”€ Resource Configuration Menu +β”‚ β”œβ”€β”€ Network Configuration Menu +β”‚ β”œβ”€β”€ select_storage() +β”‚ β”‚ β”œβ”€β”€ resolve_storage_preselect() +β”‚ β”‚ └── choose_and_set_storage_for_file() +β”‚ β”œβ”€β”€ GPU Configuration Menu +β”‚ β”‚ └── detect_gpu_devices() +β”‚ └── Feature Flags Menu +β”œβ”€β”€ build_container() +β”‚ β”œβ”€β”€ validate_settings() +β”‚ β”œβ”€β”€ check_conflicts() +β”‚ └── create_lxc_container() +└── default_var_settings() + └── Offer to save as defaults +``` + +**Key Characteristics**: +- Full interactive configuration +- Whiptail menus for all options +- Complete control over settings +- Suitable for custom deployments + +### 3. My Defaults Flow + +**Purpose**: Loads settings from global default.vars file +**Use Case**: Using previously saved global defaults + +``` +My Defaults Flow: +β”œβ”€β”€ start() +β”‚ β”œβ”€β”€ Detect execution context +β”‚ β”œβ”€β”€ Capture hard environment variables +β”‚ └── Set CT_TYPE="install" +β”œβ”€β”€ install_script() +β”‚ β”œβ”€β”€ Display installation mode menu +β”‚ β”œβ”€β”€ User selects "My Defaults" +β”‚ └── Proceed with loaded defaults +β”œβ”€β”€ variables() +β”‚ β”œβ”€β”€ base_settings() # Set built-in defaults +β”‚ β”œβ”€β”€ Load app.vars (if exists) +β”‚ β”œβ”€β”€ Load default.vars # Load global defaults +β”‚ └── Apply variable precedence +β”œβ”€β”€ build_container() +β”‚ β”œβ”€β”€ validate_settings() +β”‚ β”œβ”€β”€ check_conflicts() +β”‚ └── create_lxc_container() +└── default_var_settings() + └── Offer to save as defaults +``` + +**Key Characteristics**: +- Uses global default.vars file +- Minimal user interaction +- Consistent with previous settings +- Suitable for repeated deployments + +### 4. App Defaults Flow + +**Purpose**: Loads settings from app-specific .vars file +**Use Case**: Using previously saved app-specific defaults + +``` +App Defaults Flow: +β”œβ”€β”€ start() +β”‚ β”œβ”€β”€ Detect execution context +β”‚ β”œβ”€β”€ Capture hard environment variables +β”‚ └── Set CT_TYPE="install" +β”œβ”€β”€ install_script() +β”‚ β”œβ”€β”€ Display installation mode menu +β”‚ β”œβ”€β”€ User selects "App Defaults" +β”‚ └── Proceed with app-specific defaults +β”œβ”€β”€ variables() +β”‚ β”œβ”€β”€ base_settings() # Set built-in defaults +β”‚ β”œβ”€β”€ Load app.vars # Load app-specific defaults +β”‚ β”œβ”€β”€ Load default.vars (if exists) +β”‚ └── Apply variable precedence +β”œβ”€β”€ build_container() +β”‚ β”œβ”€β”€ validate_settings() +β”‚ β”œβ”€β”€ check_conflicts() +β”‚ └── create_lxc_container() +└── default_var_settings() + └── Offer to save as defaults +``` + +**Key Characteristics**: +- Uses app-specific .vars file +- Minimal user interaction +- App-optimized settings +- Suitable for app-specific deployments + +## Variable Precedence Chain + +### Precedence Order (Highest to Lowest) + +1. **Hard Environment Variables**: Set before script execution +2. **App-specific .vars file**: `/usr/local/community-scripts/defaults/.vars` +3. **Global default.vars file**: `/usr/local/community-scripts/default.vars` +4. **Built-in defaults**: Set in `base_settings()` function + +### Variable Resolution Process + +``` +Variable Resolution: +β”œβ”€β”€ Capture hard environment variables at start() +β”œβ”€β”€ Load built-in defaults in base_settings() +β”œβ”€β”€ Load global default.vars (if exists) +β”œβ”€β”€ Load app-specific .vars (if exists) +└── Apply precedence chain + β”œβ”€β”€ Hard env vars override all + β”œβ”€β”€ App.vars override default.vars and built-ins + β”œβ”€β”€ Default.vars override built-ins + └── Built-ins are fallback defaults +``` + +## Storage Selection Logic + +### Storage Resolution Flow + +``` +Storage Selection: +β”œβ”€β”€ Check if storage is preselected +β”‚ β”œβ”€β”€ var_template_storage set? β†’ Validate and use +β”‚ └── var_container_storage set? β†’ Validate and use +β”œβ”€β”€ Count available storage options +β”‚ β”œβ”€β”€ Only 1 option β†’ Auto-select +β”‚ └── Multiple options β†’ Prompt user +β”œβ”€β”€ User selection via whiptail +β”‚ β”œβ”€β”€ Template storage selection +β”‚ └── Container storage selection +└── Validate selected storage + β”œβ”€β”€ Check availability + β”œβ”€β”€ Check content type support + └── Proceed with selection +``` + +### Storage Validation + +``` +Storage Validation: +β”œβ”€β”€ Check storage exists +β”œβ”€β”€ Check storage is online +β”œβ”€β”€ Check content type support +β”‚ β”œβ”€β”€ Template storage: vztmpl support +β”‚ └── Container storage: rootdir support +β”œβ”€β”€ Check available space +└── Validate permissions +``` + +## GPU Passthrough Flow + +### GPU Detection and Configuration + +``` +GPU Passthrough Flow: +β”œβ”€β”€ detect_gpu_devices() +β”‚ β”œβ”€β”€ Scan for Intel GPUs +β”‚ β”‚ β”œβ”€β”€ Check i915 driver +β”‚ β”‚ └── Detect devices +β”‚ β”œβ”€β”€ Scan for AMD GPUs +β”‚ β”‚ β”œβ”€β”€ Check AMDGPU driver +β”‚ β”‚ └── Detect devices +β”‚ └── Scan for NVIDIA GPUs +β”‚ β”œβ”€β”€ Check NVIDIA driver +β”‚ β”œβ”€β”€ Detect devices +β”‚ └── Check CUDA support +β”œβ”€β”€ Check GPU passthrough eligibility +β”‚ β”œβ”€β”€ Is app in GPU_APPS list? +β”‚ β”œβ”€β”€ Is container privileged? +β”‚ └── Proceed if eligible +β”œβ”€β”€ GPU selection logic +β”‚ β”œβ”€β”€ Single GPU type β†’ Auto-select +β”‚ └── Multiple GPU types β†’ Prompt user +β”œβ”€β”€ configure_gpu_passthrough() +β”‚ β”œβ”€β”€ Add GPU device entries +β”‚ β”œβ”€β”€ Configure permissions +β”‚ └── Update container config +└── fix_gpu_gids() + β”œβ”€β”€ Update GPU group IDs + └── Configure access permissions +``` + +### GPU Eligibility Check + +``` +GPU Eligibility: +β”œβ”€β”€ Check app support +β”‚ β”œβ”€β”€ Is APP in GPU_APPS list? +β”‚ └── Proceed if supported +β”œβ”€β”€ Check container privileges +β”‚ β”œβ”€β”€ Is ENABLE_PRIVILEGED="true"? +β”‚ └── Proceed if privileged +└── Check hardware availability + β”œβ”€β”€ Are GPUs detected? + └── Proceed if available +``` + +## Network Configuration Flow + +### Network Setup Process + +``` +Network Configuration: +β”œβ”€β”€ Basic network settings +β”‚ β”œβ”€β”€ var_net (network interface) +β”‚ β”œβ”€β”€ var_bridge (bridge interface) +β”‚ └── var_gateway (gateway IP) +β”œβ”€β”€ IP configuration +β”‚ β”œβ”€β”€ var_ip (IPv4 address) +β”‚ β”œβ”€β”€ var_ipv6 (IPv6 address) +β”‚ └── IPV6_METHOD (IPv6 method) +β”œβ”€β”€ Advanced network settings +β”‚ β”œβ”€β”€ var_vlan (VLAN ID) +β”‚ β”œβ”€β”€ var_mtu (MTU size) +β”‚ └── var_mac (MAC address) +└── Network validation + β”œβ”€β”€ Check IP format + β”œβ”€β”€ Check gateway reachability + └── Validate network configuration +``` + +## Container Creation Flow + +### LXC Container Creation Process + +``` +Container Creation: +β”œβ”€β”€ create_lxc_container() +β”‚ β”œβ”€β”€ Create basic container +β”‚ β”œβ”€β”€ Configure network +β”‚ β”œβ”€β”€ Set up storage +β”‚ β”œβ”€β”€ Configure features +β”‚ β”œβ”€β”€ Set resource limits +β”‚ β”œβ”€β”€ Configure startup +β”‚ └── Start container +β”œβ”€β”€ Post-creation configuration +β”‚ β”œβ”€β”€ Wait for network +β”‚ β”œβ”€β”€ Configure GPU (if enabled) +β”‚ β”œβ”€β”€ Set up SSH keys +β”‚ └── Run post-install scripts +└── Finalization + β”œβ”€β”€ Display container info + β”œβ”€β”€ Show access details + └── Provide next steps +``` + +## Error Handling Flows + +### Validation Error Flow + +``` +Validation Error Flow: +β”œβ”€β”€ validate_settings() +β”‚ β”œβ”€β”€ Check configuration validity +β”‚ └── Return error if invalid +β”œβ”€β”€ check_conflicts() +β”‚ β”œβ”€β”€ Check for conflicts +β”‚ └── Return error if conflicts found +β”œβ”€β”€ Error handling +β”‚ β”œβ”€β”€ Display error message +β”‚ β”œβ”€β”€ cleanup_on_error() +β”‚ └── Exit with error code +└── User notification + β”œβ”€β”€ Show error details + └── Suggest fixes +``` + +### Storage Error Flow + +``` +Storage Error Flow: +β”œβ”€β”€ Storage selection fails +β”œβ”€β”€ Retry storage selection +β”‚ β”œβ”€β”€ Show available options +β”‚ └── Allow user to retry +β”œβ”€β”€ Storage validation fails +β”‚ β”œβ”€β”€ Show validation errors +β”‚ └── Allow user to fix +└── Fallback to default storage + β”œβ”€β”€ Use fallback storage + └── Continue with creation +``` + +### GPU Error Flow + +``` +GPU Error Flow: +β”œβ”€β”€ GPU detection fails +β”œβ”€β”€ Fall back to no GPU +β”‚ β”œβ”€β”€ Disable GPU passthrough +β”‚ └── Continue without GPU +β”œβ”€β”€ GPU configuration fails +β”‚ β”œβ”€β”€ Show configuration errors +β”‚ └── Allow user to retry +└── GPU permission errors + β”œβ”€β”€ Fix GPU permissions + └── Retry configuration +``` + +## Integration Flows + +### With Install Scripts + +``` +Install Script Integration: +β”œβ”€β”€ build.func creates container +β”œβ”€β”€ Container starts successfully +β”œβ”€β”€ Install script execution +β”‚ β”œβ”€β”€ Download and install app +β”‚ β”œβ”€β”€ Configure app settings +β”‚ └── Set up services +└── Post-installation configuration + β”œβ”€β”€ Verify installation + β”œβ”€β”€ Configure access + └── Display completion info +``` + +### With Proxmox API + +``` +Proxmox API Integration: +β”œβ”€β”€ API authentication +β”œβ”€β”€ Container creation via API +β”œβ”€β”€ Configuration updates via API +β”œβ”€β”€ Status monitoring via API +└── Error handling via API +``` + +## Performance Considerations + +### Execution Time Optimization + +``` +Performance Optimization: +β”œβ”€β”€ Parallel operations where possible +β”œβ”€β”€ Minimal user interaction in default mode +β”œβ”€β”€ Efficient storage selection +β”œβ”€β”€ Optimized GPU detection +└── Streamlined validation +``` + +### Resource Usage + +``` +Resource Usage: +β”œβ”€β”€ Minimal memory footprint +β”œβ”€β”€ Efficient disk usage +β”œβ”€β”€ Optimized network usage +└── Minimal CPU overhead +``` diff --git a/docs/misc/build.func/BUILD_FUNC_FLOWCHART.md b/docs/misc/build.func/BUILD_FUNC_FLOWCHART.md new file mode 100644 index 000000000..e406f46fd --- /dev/null +++ b/docs/misc/build.func/BUILD_FUNC_FLOWCHART.md @@ -0,0 +1,244 @@ +# build.func Execution Flowchart + +## Main Execution Flow + +``` +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ START() β”‚ +β”‚ Entry point when build.func is sourced or executed β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ Check Environment β”‚ +β”‚ β€’ Detect if running on Proxmox host vs inside container β”‚ +β”‚ β€’ Capture hard environment variables β”‚ +β”‚ β€’ Set CT_TYPE based on context β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ Determine Action β”‚ +β”‚ β€’ If CT_TYPE="update" β†’ update_script() β”‚ +β”‚ β€’ If CT_TYPE="install" β†’ install_script() β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ INSTALL_SCRIPT() β”‚ +β”‚ Main container creation workflow β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ Installation Mode Selection β”‚ +β”‚ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ Default β”‚ β”‚ Advanced β”‚ β”‚ My Defaults β”‚ β”‚ App Defaultsβ”‚ β”‚ +β”‚ β”‚ Install β”‚ β”‚ Install β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β€’ Use built-in β”‚ β”‚ β€’ Full whiptail β”‚ β”‚ β€’ Load from β”‚ β”‚ β€’ Load from β”‚ β”‚ +β”‚ β”‚ defaults β”‚ β”‚ menus β”‚ β”‚ default.vars β”‚ β”‚ app.vars β”‚ β”‚ +β”‚ β”‚ β€’ Minimal β”‚ β”‚ β€’ Interactive β”‚ β”‚ β€’ Override β”‚ β”‚ β€’ App- β”‚ β”‚ +β”‚ β”‚ prompts β”‚ β”‚ configuration β”‚ β”‚ built-ins β”‚ β”‚ specific β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ VARIABLES() β”‚ +β”‚ β€’ Load variable precedence chain: β”‚ +β”‚ 1. Hard environment variables β”‚ +β”‚ 2. App-specific .vars file β”‚ +β”‚ 3. Global default.vars file β”‚ +β”‚ 4. Built-in defaults in base_settings() β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ BASE_SETTINGS() β”‚ +β”‚ β€’ Set core container parameters β”‚ +β”‚ β€’ Configure OS selection β”‚ +β”‚ β€’ Set resource defaults (CPU, RAM, Disk) β”‚ +β”‚ β€’ Configure network defaults β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ Storage Selection Logic β”‚ +β”‚ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ SELECT_STORAGE() β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ +β”‚ β”‚ β”‚ Template β”‚ β”‚ Container β”‚ β”‚ Resolution β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ Storage β”‚ β”‚ Storage β”‚ β”‚ Logic β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ Check if β”‚ β”‚ β€’ Check if β”‚ β”‚ 1. Only 1 storage β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ preselected β”‚ β”‚ preselected β”‚ β”‚ β†’ Auto-select β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ Validate β”‚ β”‚ β€’ Validate β”‚ β”‚ 2. Preselected β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ availability β”‚ β”‚ availability β”‚ β”‚ β†’ Validate & use β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ Prompt if β”‚ β”‚ β€’ Prompt if β”‚ β”‚ 3. Multiple options β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ needed β”‚ β”‚ needed β”‚ β”‚ β†’ Prompt user β”‚ β”‚ β”‚ +β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ BUILD_CONTAINER() β”‚ +β”‚ β€’ Validate all settings β”‚ +β”‚ β€’ Check for conflicts β”‚ +β”‚ β€’ Prepare container configuration β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ CREATE_LXC_CONTAINER() β”‚ +β”‚ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ Container Creation Process β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ 1. Create LXC container with basic configuration β”‚ β”‚ +β”‚ β”‚ 2. Configure network settings β”‚ β”‚ +β”‚ β”‚ 3. Set up storage and mount points β”‚ β”‚ +β”‚ β”‚ 4. Configure features (FUSE, TUN, etc.) β”‚ β”‚ +β”‚ β”‚ 5. Set resource limits β”‚ β”‚ +β”‚ β”‚ 6. Configure startup options β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ GPU Passthrough Decision Tree β”‚ +β”‚ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ DETECT_GPU_DEVICES() β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ +β”‚ β”‚ β”‚ Intel GPU β”‚ β”‚ AMD GPU β”‚ β”‚ NVIDIA GPU β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ Check i915 β”‚ β”‚ β€’ Check AMDGPU β”‚ β”‚ β€’ Check NVIDIA β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ driver β”‚ β”‚ driver β”‚ β”‚ driver β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ Detect β”‚ β”‚ β€’ Detect β”‚ β”‚ β€’ Detect devices β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ devices β”‚ β”‚ devices β”‚ β”‚ β€’ Check CUDA support β”‚ β”‚ β”‚ +β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β”‚ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ GPU Selection Logic β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β€’ Is app in GPU_APPS list? OR Is container privileged? β”‚ β”‚ +β”‚ β”‚ └─ YES β†’ Proceed with GPU configuration β”‚ β”‚ +β”‚ β”‚ └─ NO β†’ Skip GPU passthrough β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β€’ Single GPU type detected? β”‚ β”‚ +β”‚ β”‚ └─ YES β†’ Auto-select and configure β”‚ β”‚ +β”‚ β”‚ └─ NO β†’ Prompt user for selection β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ CONFIGURE_GPU_PASSTHROUGH() β”‚ +β”‚ β€’ Add GPU device entries to /etc/pve/lxc/.conf β”‚ +β”‚ β€’ Configure proper device permissions β”‚ +β”‚ β€’ Set up device mapping β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ Container Finalization β”‚ +β”‚ β€’ Start container β”‚ +β”‚ β€’ Wait for network connectivity β”‚ +β”‚ β€’ Fix GPU GIDs (if GPU passthrough enabled) β”‚ +β”‚ β€’ Configure SSH keys (if enabled) β”‚ +β”‚ β€’ Run post-installation scripts β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ Settings Persistence β”‚ +β”‚ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ DEFAULT_VAR_SETTINGS() β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β€’ Offer to save current settings as defaults β”‚ β”‚ +β”‚ β”‚ β€’ Save to /usr/local/community-scripts/default.vars β”‚ β”‚ +β”‚ β”‚ β€’ Save to /usr/local/community-scripts/defaults/.vars β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ COMPLETION β”‚ +β”‚ β€’ Display container information β”‚ +β”‚ β€’ Show access details β”‚ +β”‚ β€’ Provide next steps β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +``` + +## Key Decision Points + +### 1. Installation Mode Selection +- **Default**: Uses built-in defaults, minimal user interaction +- **Advanced**: Full interactive configuration via whiptail menus +- **My Defaults**: Loads settings from global default.vars file +- **App Defaults**: Loads settings from app-specific .vars file + +### 2. Storage Selection Logic +``` +Storage Selection Flow: +β”œβ”€β”€ Check if storage is preselected via environment variables +β”‚ β”œβ”€β”€ YES β†’ Validate availability and use +β”‚ └── NO β†’ Continue to resolution logic +β”œβ”€β”€ Count available storage options for content type +β”‚ β”œβ”€β”€ Only 1 option β†’ Auto-select +β”‚ └── Multiple options β†’ Prompt user via whiptail +└── Validate selected storage and proceed +``` + +### 3. GPU Passthrough Decision Tree +``` +GPU Passthrough Flow: +β”œβ”€β”€ Detect available GPU hardware +β”‚ β”œβ”€β”€ Intel GPU detected +β”‚ β”œβ”€β”€ AMD GPU detected +β”‚ └── NVIDIA GPU detected +β”œβ”€β”€ Check if GPU passthrough should be enabled +β”‚ β”œβ”€β”€ App is in GPU_APPS list? β†’ YES +β”‚ β”œβ”€β”€ Container is privileged? β†’ YES +β”‚ └── Neither? β†’ Skip GPU passthrough +β”œβ”€β”€ Configure GPU passthrough +β”‚ β”œβ”€β”€ Single GPU type β†’ Auto-configure +β”‚ └── Multiple GPU types β†’ Prompt user +└── Fix GPU GIDs post-creation +``` + +### 4. Variable Precedence Chain +``` +Variable Resolution Order: +1. Hard environment variables (captured at start) +2. App-specific .vars file (/usr/local/community-scripts/defaults/.vars) +3. Global default.vars file (/usr/local/community-scripts/default.vars) +4. Built-in defaults in base_settings() function +``` + +## Error Handling Flow + +``` +Error Handling: +β”œβ”€β”€ Validation errors β†’ Display error message and exit +β”œβ”€β”€ Storage errors β†’ Retry storage selection +β”œβ”€β”€ Network errors β†’ Retry network configuration +β”œβ”€β”€ GPU errors β†’ Fall back to no GPU passthrough +└── Container creation errors β†’ Cleanup and exit +``` + +## Integration Points + +- **Core Functions**: Depends on core.func for basic utilities +- **Error Handling**: Uses error_handler.func for error management +- **API Functions**: Uses api.func for Proxmox API interactions +- **Tools**: Uses tools.func for additional utilities +- **Install Scripts**: Integrates with -install.sh scripts diff --git a/docs/misc/build.func/BUILD_FUNC_FUNCTIONS_REFERENCE.md b/docs/misc/build.func/BUILD_FUNC_FUNCTIONS_REFERENCE.md new file mode 100644 index 000000000..a8128d4e9 --- /dev/null +++ b/docs/misc/build.func/BUILD_FUNC_FUNCTIONS_REFERENCE.md @@ -0,0 +1,361 @@ +# build.func Functions Reference + +## Overview + +This document provides a comprehensive reference of all functions in `build.func`, organized alphabetically with detailed descriptions, parameters, and usage information. + +## Function Categories + +### Initialization Functions + +#### `start()` +**Purpose**: Main entry point when build.func is sourced or executed +**Parameters**: None +**Returns**: None +**Side Effects**: +- Detects execution context (Proxmox host vs container) +- Captures hard environment variables +- Sets CT_TYPE based on context +- Routes to appropriate workflow (install_script or update_script) +**Dependencies**: None +**Environment Variables Used**: `CT_TYPE`, `APP`, `CTID` + +#### `variables()` +**Purpose**: Load and resolve all configuration variables using precedence chain +**Parameters**: None +**Returns**: None +**Side Effects**: +- Loads app-specific .vars file +- Loads global default.vars file +- Applies variable precedence chain +- Sets all configuration variables +**Dependencies**: `base_settings()` +**Environment Variables Used**: All configuration variables + +#### `base_settings()` +**Purpose**: Set built-in default values for all configuration variables +**Parameters**: None +**Returns**: None +**Side Effects**: Sets default values for all variables +**Dependencies**: None +**Environment Variables Used**: All configuration variables + +### UI and Menu Functions + +#### `install_script()` +**Purpose**: Main installation workflow coordinator +**Parameters**: None +**Returns**: None +**Side Effects**: +- Displays installation mode selection menu +- Coordinates the entire installation process +- Handles user interaction and validation +**Dependencies**: `variables()`, `build_container()`, `default_var_settings()` +**Environment Variables Used**: `APP`, `CTID`, `var_hostname` + +#### `advanced_settings()` +**Purpose**: Provide advanced configuration options via whiptail menus +**Parameters**: None +**Returns**: None +**Side Effects**: +- Displays whiptail menus for configuration +- Updates configuration variables based on user input +- Validates user selections +**Dependencies**: `select_storage()`, `detect_gpu_devices()` +**Environment Variables Used**: All configuration variables + +#### `settings_menu()` +**Purpose**: Display and handle settings configuration menu +**Parameters**: None +**Returns**: None +**Side Effects**: Updates configuration variables +**Dependencies**: `advanced_settings()` +**Environment Variables Used**: All configuration variables + +### Storage Functions + +#### `select_storage()` +**Purpose**: Handle storage selection for templates and containers +**Parameters**: None +**Returns**: None +**Side Effects**: +- Resolves storage preselection +- Prompts user for storage selection if needed +- Validates storage availability +- Sets var_template_storage and var_container_storage +**Dependencies**: `resolve_storage_preselect()`, `choose_and_set_storage_for_file()` +**Environment Variables Used**: `var_template_storage`, `var_container_storage`, `TEMPLATE_STORAGE`, `CONTAINER_STORAGE` + +#### `resolve_storage_preselect()` +**Purpose**: Resolve preselected storage options +**Parameters**: +- `storage_type`: Type of storage (template or container) +**Returns**: Storage name if valid, empty if invalid +**Side Effects**: Validates storage availability +**Dependencies**: None +**Environment Variables Used**: `var_template_storage`, `var_container_storage` + +#### `choose_and_set_storage_for_file()` +**Purpose**: Interactive storage selection via whiptail +**Parameters**: +- `storage_type`: Type of storage (template or container) +- `content_type`: Content type (vztmpl or rootdir) +**Returns**: None +**Side Effects**: +- Displays whiptail menu +- Updates storage variables +- Validates selection +**Dependencies**: None +**Environment Variables Used**: `var_template_storage`, `var_container_storage` + +### Container Creation Functions + +#### `build_container()` +**Purpose**: Validate settings and prepare container creation +**Parameters**: None +**Returns**: None +**Side Effects**: +- Validates all configuration +- Checks for conflicts +- Prepares container configuration +- Calls create_lxc_container() +**Dependencies**: `create_lxc_container()` +**Environment Variables Used**: All configuration variables + +#### `create_lxc_container()` +**Purpose**: Create the actual LXC container +**Parameters**: None +**Returns**: None +**Side Effects**: +- Creates LXC container with basic configuration +- Configures network settings +- Sets up storage and mount points +- Configures features (FUSE, TUN, etc.) +- Sets resource limits +- Configures startup options +- Starts container +**Dependencies**: `configure_gpu_passthrough()`, `fix_gpu_gids()` +**Environment Variables Used**: All configuration variables + +### GPU and Hardware Functions + +#### `detect_gpu_devices()` +**Purpose**: Detect available GPU hardware on the system +**Parameters**: None +**Returns**: None +**Side Effects**: +- Scans for Intel, AMD, and NVIDIA GPUs +- Updates var_gpu_type and var_gpu_devices +- Determines GPU capabilities +**Dependencies**: None +**Environment Variables Used**: `var_gpu_type`, `var_gpu_devices`, `GPU_APPS` + +#### `configure_gpu_passthrough()` +**Purpose**: Configure GPU passthrough for the container +**Parameters**: None +**Returns**: None +**Side Effects**: +- Adds GPU device entries to container config +- Configures proper device permissions +- Sets up device mapping +- Updates /etc/pve/lxc/.conf +**Dependencies**: `detect_gpu_devices()` +**Environment Variables Used**: `var_gpu`, `var_gpu_type`, `var_gpu_devices`, `CTID` + +#### `fix_gpu_gids()` +**Purpose**: Fix GPU group IDs after container creation +**Parameters**: None +**Returns**: None +**Side Effects**: +- Updates GPU group IDs in container +- Ensures proper GPU access permissions +- Configures video and render groups +**Dependencies**: `configure_gpu_passthrough()` +**Environment Variables Used**: `CTID`, `var_gpu_type` + +### Settings Persistence Functions + +#### `default_var_settings()` +**Purpose**: Offer to save current settings as defaults +**Parameters**: None +**Returns**: None +**Side Effects**: +- Prompts user to save settings +- Saves to default.vars file +- Saves to app-specific .vars file +**Dependencies**: `maybe_offer_save_app_defaults()` +**Environment Variables Used**: All configuration variables + +#### `maybe_offer_save_app_defaults()` +**Purpose**: Offer to save app-specific defaults +**Parameters**: None +**Returns**: None +**Side Effects**: +- Prompts user to save app-specific settings +- Saves to app.vars file +- Updates app-specific configuration +**Dependencies**: None +**Environment Variables Used**: `APP`, `SAVE_APP_DEFAULTS` + +### Utility Functions + +#### `validate_settings()` +**Purpose**: Validate all configuration settings +**Parameters**: None +**Returns**: 0 if valid, 1 if invalid +**Side Effects**: +- Checks for configuration conflicts +- Validates resource limits +- Validates network configuration +- Validates storage configuration +**Dependencies**: None +**Environment Variables Used**: All configuration variables + +#### `check_conflicts()` +**Purpose**: Check for configuration conflicts +**Parameters**: None +**Returns**: 0 if no conflicts, 1 if conflicts found +**Side Effects**: +- Checks for conflicting settings +- Validates resource allocation +- Checks network configuration +**Dependencies**: None +**Environment Variables Used**: All configuration variables + +#### `cleanup_on_error()` +**Purpose**: Clean up resources on error +**Parameters**: None +**Returns**: None +**Side Effects**: +- Removes partially created containers +- Cleans up temporary files +- Resets configuration +**Dependencies**: None +**Environment Variables Used**: `CTID` + +## Function Call Flow + +### Main Installation Flow +``` +start() +β”œβ”€β”€ variables() +β”‚ β”œβ”€β”€ base_settings() +β”‚ β”œβ”€β”€ Load app.vars +β”‚ └── Load default.vars +β”œβ”€β”€ install_script() +β”‚ β”œβ”€β”€ advanced_settings() +β”‚ β”‚ β”œβ”€β”€ select_storage() +β”‚ β”‚ β”‚ β”œβ”€β”€ resolve_storage_preselect() +β”‚ β”‚ β”‚ └── choose_and_set_storage_for_file() +β”‚ β”‚ └── detect_gpu_devices() +β”‚ β”œβ”€β”€ build_container() +β”‚ β”‚ β”œβ”€β”€ validate_settings() +β”‚ β”‚ β”œβ”€β”€ check_conflicts() +β”‚ β”‚ └── create_lxc_container() +β”‚ β”‚ β”œβ”€β”€ configure_gpu_passthrough() +β”‚ β”‚ └── fix_gpu_gids() +β”‚ └── default_var_settings() +β”‚ └── maybe_offer_save_app_defaults() +``` + +### Error Handling Flow +``` +Error Detection +β”œβ”€β”€ validate_settings() +β”‚ └── check_conflicts() +β”œβ”€β”€ Error Handling +β”‚ └── cleanup_on_error() +└── Exit with error code +``` + +## Function Dependencies + +### Core Dependencies +- `start()` β†’ `install_script()` β†’ `build_container()` β†’ `create_lxc_container()` +- `variables()` β†’ `base_settings()` +- `advanced_settings()` β†’ `select_storage()` β†’ `detect_gpu_devices()` + +### Storage Dependencies +- `select_storage()` β†’ `resolve_storage_preselect()` +- `select_storage()` β†’ `choose_and_set_storage_for_file()` + +### GPU Dependencies +- `configure_gpu_passthrough()` β†’ `detect_gpu_devices()` +- `fix_gpu_gids()` β†’ `configure_gpu_passthrough()` + +### Settings Dependencies +- `default_var_settings()` β†’ `maybe_offer_save_app_defaults()` + +## Function Usage Examples + +### Basic Container Creation +```bash +# Set required variables +export APP="plex" +export CTID="100" +export var_hostname="plex-server" + +# Call main functions +start() # Entry point +# β†’ variables() # Load configuration +# β†’ install_script() # Main workflow +# β†’ build_container() # Create container +# β†’ create_lxc_container() # Actual creation +``` + +### Advanced Configuration +```bash +# Set advanced variables +export var_os="debian" +export var_version="12" +export var_cpu="4" +export var_ram="4096" +export var_disk="20" + +# Call advanced functions +advanced_settings() # Interactive configuration +# β†’ select_storage() # Storage selection +# β†’ detect_gpu_devices() # GPU detection +``` + +### GPU Passthrough +```bash +# Enable GPU passthrough +export GPU_APPS="plex" +export var_gpu="nvidia" + +# Call GPU functions +detect_gpu_devices() # Detect hardware +configure_gpu_passthrough() # Configure passthrough +fix_gpu_gids() # Fix permissions +``` + +### Settings Persistence +```bash +# Save settings as defaults +export SAVE_DEFAULTS="true" +export SAVE_APP_DEFAULTS="true" + +# Call persistence functions +default_var_settings() # Save global defaults +maybe_offer_save_app_defaults() # Save app defaults +``` + +## Function Error Handling + +### Validation Functions +- `validate_settings()`: Returns 0 for valid, 1 for invalid +- `check_conflicts()`: Returns 0 for no conflicts, 1 for conflicts + +### Error Recovery +- `cleanup_on_error()`: Cleans up on any error +- Error codes are propagated up the call stack +- Critical errors cause script termination + +### Error Types +1. **Configuration Errors**: Invalid settings or conflicts +2. **Resource Errors**: Insufficient resources or conflicts +3. **Network Errors**: Invalid network configuration +4. **Storage Errors**: Storage not available or invalid +5. **GPU Errors**: GPU configuration failures +6. **Container Creation Errors**: LXC creation failures diff --git a/docs/misc/build.func/BUILD_FUNC_USAGE_EXAMPLES.md b/docs/misc/build.func/BUILD_FUNC_USAGE_EXAMPLES.md new file mode 100644 index 000000000..b5ad83d6e --- /dev/null +++ b/docs/misc/build.func/BUILD_FUNC_USAGE_EXAMPLES.md @@ -0,0 +1,600 @@ +# build.func Usage Examples + +## Overview + +This document provides practical usage examples for `build.func`, covering common scenarios, CLI examples, and environment variable combinations. + +## Basic Usage Examples + +### 1. Simple Container Creation + +**Scenario**: Create a basic Plex media server container + +```bash +# Set basic environment variables +export APP="plex" +export CTID="100" +export var_hostname="plex-server" +export var_os="debian" +export var_version="12" +export var_cpu="4" +export var_ram="4096" +export var_disk="20" +export var_net="vmbr0" +export var_gateway="192.168.1.1" +export var_ip="192.168.1.100" +export var_template_storage="local" +export var_container_storage="local" + +# Execute build.func +source build.func +``` + +**Expected Output**: +``` +Creating Plex container... +Container ID: 100 +Hostname: plex-server +OS: Debian 12 +Resources: 4 CPU, 4GB RAM, 20GB Disk +Network: 192.168.1.100/24 +Container created successfully! +``` + +### 2. Advanced Configuration + +**Scenario**: Create a Nextcloud container with custom settings + +```bash +# Set advanced environment variables +export APP="nextcloud" +export CTID="101" +export var_hostname="nextcloud-server" +export var_os="ubuntu" +export var_version="22.04" +export var_cpu="6" +export var_ram="8192" +export var_disk="50" +export var_net="vmbr0" +export var_gateway="192.168.1.1" +export var_ip="192.168.1.101" +export var_vlan="100" +export var_mtu="9000" +export var_template_storage="nfs-storage" +export var_container_storage="ssd-storage" +export ENABLE_FUSE="true" +export ENABLE_TUN="true" +export SSH="true" + +# Execute build.func +source build.func +``` + +### 3. GPU Passthrough Configuration + +**Scenario**: Create a Jellyfin container with NVIDIA GPU passthrough + +```bash +# Set GPU passthrough variables +export APP="jellyfin" +export CTID="102" +export var_hostname="jellyfin-server" +export var_os="debian" +export var_version="12" +export var_cpu="8" +export var_ram="16384" +export var_disk="30" +export var_net="vmbr0" +export var_gateway="192.168.1.1" +export var_ip="192.168.1.102" +export var_template_storage="local" +export var_container_storage="local" +export GPU_APPS="jellyfin" +export var_gpu="nvidia" +export ENABLE_PRIVILEGED="true" +export ENABLE_FUSE="true" +export ENABLE_TUN="true" + +# Execute build.func +source build.func +``` + +## Silent/Non-Interactive Examples + +### 1. Automated Deployment + +**Scenario**: Deploy multiple containers without user interaction + +```bash +#!/bin/bash +# Automated deployment script + +# Function to create container +create_container() { + local app=$1 + local ctid=$2 + local ip=$3 + + 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="$ip" + export var_template_storage="local" + export var_container_storage="local" + export ENABLE_FUSE="true" + export ENABLE_TUN="true" + export SSH="true" + + source build.func +} + +# Create multiple containers +create_container "plex" "100" "192.168.1.100" +create_container "nextcloud" "101" "192.168.1.101" +create_container "nginx" "102" "192.168.1.102" +``` + +### 2. Development Environment Setup + +**Scenario**: Create development containers with specific configurations + +```bash +#!/bin/bash +# Development environment setup + +# Development container configuration +export APP="dev-container" +export CTID="200" +export var_hostname="dev-server" +export var_os="ubuntu" +export var_version="22.04" +export var_cpu="4" +export var_ram="4096" +export var_disk="20" +export var_net="vmbr0" +export var_gateway="192.168.1.1" +export var_ip="192.168.1.200" +export var_template_storage="local" +export var_container_storage="local" +export ENABLE_NESTING="true" +export ENABLE_PRIVILEGED="true" +export ENABLE_FUSE="true" +export ENABLE_TUN="true" +export SSH="true" + +# Execute build.func +source build.func +``` + +## Network Configuration Examples + +### 1. VLAN Configuration + +**Scenario**: Create container with VLAN support + +```bash +# VLAN configuration +export APP="web-server" +export CTID="300" +export var_hostname="web-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.100.1" +export var_ip="192.168.100.100" +export var_vlan="100" +export var_mtu="1500" +export var_template_storage="local" +export var_container_storage="local" + +source build.func +``` + +### 2. IPv6 Configuration + +**Scenario**: Create container with IPv6 support + +```bash +# IPv6 configuration +export APP="ipv6-server" +export CTID="301" +export var_hostname="ipv6-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.101" +export var_ipv6="2001:db8::101" +export IPV6_METHOD="static" +export var_template_storage="local" +export var_container_storage="local" + +source build.func +``` + +## Storage Configuration Examples + +### 1. Custom Storage Locations + +**Scenario**: Use different storage for templates and containers + +```bash +# Custom storage configuration +export APP="storage-test" +export CTID="400" +export var_hostname="storage-test" +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.140" +export var_template_storage="nfs-storage" +export var_container_storage="ssd-storage" + +source build.func +``` + +### 2. High-Performance Storage + +**Scenario**: Use high-performance storage for resource-intensive applications + +```bash +# High-performance storage configuration +export APP="database-server" +export CTID="401" +export var_hostname="database-server" +export var_os="debian" +export var_version="12" +export var_cpu="8" +export var_ram="16384" +export var_disk="100" +export var_net="vmbr0" +export var_gateway="192.168.1.1" +export var_ip="192.168.1.141" +export var_template_storage="nvme-storage" +export var_container_storage="nvme-storage" + +source build.func +``` + +## Feature Configuration Examples + +### 1. Privileged Container + +**Scenario**: Create privileged container for system-level access + +```bash +# Privileged container configuration +export APP="system-container" +export CTID="500" +export var_hostname="system-container" +export var_os="debian" +export var_version="12" +export var_cpu="4" +export var_ram="4096" +export var_disk="20" +export var_net="vmbr0" +export var_gateway="192.168.1.1" +export var_ip="192.168.1.150" +export var_template_storage="local" +export var_container_storage="local" +export ENABLE_PRIVILEGED="true" +export ENABLE_FUSE="true" +export ENABLE_TUN="true" +export ENABLE_KEYCTL="true" +export ENABLE_MOUNT="true" + +source build.func +``` + +### 2. Unprivileged Container + +**Scenario**: Create secure unprivileged container + +```bash +# Unprivileged container configuration +export APP="secure-container" +export CTID="501" +export var_hostname="secure-container" +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.151" +export var_template_storage="local" +export var_container_storage="local" +export ENABLE_UNPRIVILEGED="true" +export ENABLE_FUSE="true" +export ENABLE_TUN="true" + +source build.func +``` + +## Settings Persistence Examples + +### 1. Save Global Defaults + +**Scenario**: Save current settings as global defaults + +```bash +# Save global defaults +export APP="default-test" +export CTID="600" +export var_hostname="default-test" +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.160" +export var_template_storage="local" +export var_container_storage="local" +export SAVE_DEFAULTS="true" + +source build.func +``` + +### 2. Save App-Specific Defaults + +**Scenario**: Save settings as app-specific defaults + +```bash +# Save app-specific defaults +export APP="plex" +export CTID="601" +export var_hostname="plex-server" +export var_os="debian" +export var_version="12" +export var_cpu="4" +export var_ram="4096" +export var_disk="20" +export var_net="vmbr0" +export var_gateway="192.168.1.1" +export var_ip="192.168.1.161" +export var_template_storage="local" +export var_container_storage="local" +export SAVE_APP_DEFAULTS="true" + +source build.func +``` + +## Error Handling Examples + +### 1. Validation Error Handling + +**Scenario**: Handle configuration validation errors + +```bash +#!/bin/bash +# Error handling example + +# Set invalid configuration +export APP="error-test" +export CTID="700" +export var_hostname="error-test" +export var_os="invalid-os" +export var_version="invalid-version" +export var_cpu="invalid-cpu" +export var_ram="invalid-ram" +export var_disk="invalid-disk" +export var_net="invalid-network" +export var_gateway="invalid-gateway" +export var_ip="invalid-ip" + +# Execute with error handling +if source build.func; then + echo "Container created successfully!" +else + echo "Error: Container creation failed!" + echo "Please check your configuration and try again." +fi +``` + +### 2. Storage Error Handling + +**Scenario**: Handle storage selection errors + +```bash +#!/bin/bash +# Storage error handling + +# Set invalid storage +export APP="storage-error-test" +export CTID="701" +export var_hostname="storage-error-test" +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.170" +export var_template_storage="nonexistent-storage" +export var_container_storage="nonexistent-storage" + +# Execute with error handling +if source build.func; then + echo "Container created successfully!" +else + echo "Error: Storage not available!" + echo "Please check available storage and try again." +fi +``` + +## Integration Examples + +### 1. With Install Scripts + +**Scenario**: Integrate with application install scripts + +```bash +#!/bin/bash +# Integration with install scripts + +# Create container +export APP="plex" +export CTID="800" +export var_hostname="plex-server" +export var_os="debian" +export var_version="12" +export var_cpu="4" +export var_ram="4096" +export var_disk="20" +export var_net="vmbr0" +export var_gateway="192.168.1.1" +export var_ip="192.168.1.180" +export var_template_storage="local" +export var_container_storage="local" + +# Create container +source build.func + +# Run install script +if [ -f "plex-install.sh" ]; then + source plex-install.sh +else + echo "Install script not found!" +fi +``` + +### 2. With Monitoring + +**Scenario**: Integrate with monitoring systems + +```bash +#!/bin/bash +# Monitoring integration + +# Create container with monitoring +export APP="monitored-app" +export CTID="801" +export var_hostname="monitored-app" +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.181" +export var_template_storage="local" +export var_container_storage="local" +export DIAGNOSTICS="true" + +# Create container +source build.func + +# Set up monitoring +if [ -f "monitoring-setup.sh" ]; then + source monitoring-setup.sh +fi +``` + +## Best Practices + +### 1. Environment Variable Management + +```bash +#!/bin/bash +# Best practice: Environment variable management + +# Set configuration file +CONFIG_FILE="/etc/build.func.conf" + +# Load configuration if exists +if [ -f "$CONFIG_FILE" ]; then + source "$CONFIG_FILE" +fi + +# Set required variables +export APP="${APP:-plex}" +export CTID="${CTID:-100}" +export var_hostname="${var_hostname:-plex-server}" +export var_os="${var_os:-debian}" +export var_version="${var_version:-12}" +export var_cpu="${var_cpu:-2}" +export var_ram="${var_ram:-2048}" +export var_disk="${var_disk:-10}" +export var_net="${var_net:-vmbr0}" +export var_gateway="${var_gateway:-192.168.1.1}" +export var_ip="${var_ip:-192.168.1.100}" +export var_template_storage="${var_template_storage:-local}" +export var_container_storage="${var_container_storage:-local}" + +# Execute build.func +source build.func +``` + +### 2. Error Handling and Logging + +```bash +#!/bin/bash +# Best practice: Error handling and logging + +# Set log file +LOG_FILE="/var/log/build.func.log" + +# Function to log messages +log_message() { + echo "$(date): $1" >> "$LOG_FILE" +} + +# Function to create container with error handling +create_container() { + local app=$1 + local ctid=$2 + + log_message "Starting container creation for $app (ID: $ctid)" + + # Set variables + 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" + + # Create container + if source build.func; then + log_message "Container $app created successfully (ID: $ctid)" + return 0 + else + log_message "Error: Failed to create container $app (ID: $ctid)" + return 1 + fi +} + +# Create containers +create_container "plex" "100" +create_container "nextcloud" "101" +create_container "nginx" "102" +``` diff --git a/docs/misc/build.func/README.md b/docs/misc/build.func/README.md new file mode 100644 index 000000000..c7ede47c7 --- /dev/null +++ b/docs/misc/build.func/README.md @@ -0,0 +1,260 @@ +# build.func Documentation + +## Overview + +This directory contains comprehensive documentation for the `build.func` script, which is the core orchestration script for Proxmox LXC container creation in the Community Scripts project. + +## Documentation Files + +### πŸ“Š [BUILD_FUNC_FLOWCHART.md](./BUILD_FUNC_FLOWCHART.md) +Visual ASCII flowchart showing the main execution flow, decision trees, and key decision points in the build.func script. + +**Contents:** +- Main execution flow diagram +- Installation mode selection flows +- Storage selection workflow +- GPU passthrough decision logic +- Variable precedence chain +- Error handling flow +- Integration points + +### πŸ”§ [BUILD_FUNC_ENVIRONMENT_VARIABLES.md](./BUILD_FUNC_ENVIRONMENT_VARIABLES.md) +Complete reference of all environment variables used in build.func, organized by category and usage context. + +**Contents:** +- Core container variables +- Operating system variables +- Resource configuration variables +- Network configuration variables +- Storage configuration variables +- Feature flags +- GPU passthrough variables +- API and diagnostics variables +- Settings persistence variables +- Variable precedence chain +- Critical variables for non-interactive use +- Common variable combinations + +### πŸ“š [BUILD_FUNC_FUNCTIONS_REFERENCE.md](./BUILD_FUNC_FUNCTIONS_REFERENCE.md) +Alphabetical function reference with detailed descriptions, parameters, dependencies, and usage information. + +**Contents:** +- Initialization functions +- UI and menu functions +- Storage functions +- Container creation functions +- GPU and hardware functions +- Settings persistence functions +- Utility functions +- Function call flow +- Function dependencies +- Function usage examples +- Function error handling + +### πŸ”„ [BUILD_FUNC_EXECUTION_FLOWS.md](./BUILD_FUNC_EXECUTION_FLOWS.md) +Detailed execution flows for different installation modes and scenarios, including variable precedence and decision trees. + +**Contents:** +- Default install flow +- Advanced install flow +- My defaults flow +- App defaults flow +- Variable precedence chain +- Storage selection logic +- GPU passthrough flow +- Network configuration flow +- Container creation flow +- Error handling flows +- Integration flows +- Performance considerations + +### πŸ—οΈ [BUILD_FUNC_ARCHITECTURE.md](./BUILD_FUNC_ARCHITECTURE.md) +High-level architectural overview including module dependencies, data flow, integration points, and system architecture. + +**Contents:** +- High-level architecture diagram +- Module dependencies +- Data flow architecture +- Integration architecture +- System architecture components +- User interface components +- Security architecture +- Performance architecture +- Deployment architecture +- Maintenance architecture +- Future architecture considerations + +### πŸ’‘ [BUILD_FUNC_USAGE_EXAMPLES.md](./BUILD_FUNC_USAGE_EXAMPLES.md) +Practical usage examples covering common scenarios, CLI examples, and environment variable combinations. + +**Contents:** +- Basic usage examples +- Silent/non-interactive examples +- Network configuration examples +- Storage configuration examples +- Feature configuration examples +- Settings persistence examples +- Error handling examples +- Integration examples +- Best practices + +## Quick Start Guide + +### For New Users +1. Start with [BUILD_FUNC_FLOWCHART.md](./BUILD_FUNC_FLOWCHART.md) to understand the overall flow +2. Review [BUILD_FUNC_ENVIRONMENT_VARIABLES.md](./BUILD_FUNC_ENVIRONMENT_VARIABLES.md) for configuration options +3. Follow examples in [BUILD_FUNC_USAGE_EXAMPLES.md](./BUILD_FUNC_USAGE_EXAMPLES.md) + +### For Developers +1. Read [BUILD_FUNC_ARCHITECTURE.md](./BUILD_FUNC_ARCHITECTURE.md) for system overview +2. Study [BUILD_FUNC_FUNCTIONS_REFERENCE.md](./BUILD_FUNC_FUNCTIONS_REFERENCE.md) for function details +3. Review [BUILD_FUNC_EXECUTION_FLOWS.md](./BUILD_FUNC_EXECUTION_FLOWS.md) for implementation details + +### For System Administrators +1. Focus on [BUILD_FUNC_USAGE_EXAMPLES.md](./BUILD_FUNC_USAGE_EXAMPLES.md) for deployment scenarios +2. Review [BUILD_FUNC_ENVIRONMENT_VARIABLES.md](./BUILD_FUNC_ENVIRONMENT_VARIABLES.md) for configuration management +3. Check [BUILD_FUNC_ARCHITECTURE.md](./BUILD_FUNC_ARCHITECTURE.md) for security and performance considerations + +## Key Concepts + +### Variable Precedence +Variables are resolved in this order (highest to lowest priority): +1. Hard environment variables (set before script execution) +2. App-specific .vars file (`/usr/local/community-scripts/defaults/.vars`) +3. Global default.vars file (`/usr/local/community-scripts/default.vars`) +4. Built-in defaults (set in `base_settings()` function) + +### Installation Modes +- **Default Install**: Uses built-in defaults, minimal prompts +- **Advanced Install**: Full interactive configuration via whiptail +- **My Defaults**: Loads from global default.vars file +- **App Defaults**: Loads from app-specific .vars file + +### Storage Selection Logic +1. If only 1 storage exists for content type β†’ auto-select +2. If preselected via environment variables β†’ validate and use +3. Otherwise β†’ prompt user via whiptail + +### GPU Passthrough Flow +1. Detect hardware (Intel/AMD/NVIDIA) +2. Check if app is in GPU_APPS list OR container is privileged +3. Auto-select if single GPU type, prompt if multiple +4. Configure `/etc/pve/lxc/.conf` with proper device entries +5. Fix GIDs post-creation to match container's video/render groups + +## Common Use Cases + +### Basic Container Creation +```bash +export APP="plex" +export CTID="100" +export var_hostname="plex-server" +export var_os="debian" +export var_version="12" +export var_cpu="4" +export var_ram="4096" +export var_disk="20" +export var_net="vmbr0" +export var_gateway="192.168.1.1" +export var_ip="192.168.1.100" +export var_template_storage="local" +export var_container_storage="local" + +source build.func +``` + +### GPU Passthrough +```bash +export APP="jellyfin" +export CTID="101" +export var_hostname="jellyfin-server" +export var_os="debian" +export var_version="12" +export var_cpu="8" +export var_ram="16384" +export var_disk="30" +export var_net="vmbr0" +export var_gateway="192.168.1.1" +export var_ip="192.168.1.101" +export var_template_storage="local" +export var_container_storage="local" +export GPU_APPS="jellyfin" +export var_gpu="nvidia" +export ENABLE_PRIVILEGED="true" + +source build.func +``` + +### Silent/Non-Interactive Deployment +```bash +#!/bin/bash +# Automated deployment +export APP="nginx" +export CTID="102" +export var_hostname="nginx-proxy" +export var_os="alpine" +export var_version="3.18" +export var_cpu="1" +export var_ram="512" +export var_disk="2" +export var_net="vmbr0" +export var_gateway="192.168.1.1" +export var_ip="192.168.1.102" +export var_template_storage="local" +export var_container_storage="local" +export ENABLE_UNPRIVILEGED="true" + +source build.func +``` + +## Troubleshooting + +### Common Issues +1. **Container creation fails**: Check resource availability and configuration validity +2. **Storage errors**: Verify storage exists and supports required content types +3. **Network errors**: Validate network configuration and IP address availability +4. **GPU passthrough issues**: Check hardware detection and container privileges +5. **Permission errors**: Verify user permissions and container privileges + +### Debug Mode +Enable verbose output for debugging: +```bash +export VERBOSE="true" +export DIAGNOSTICS="true" +source build.func +``` + +### Log Files +Check system logs for detailed error information: +- `/var/log/syslog` +- `/var/log/pve/lxc/.log` +- Container-specific logs + +## Contributing + +When contributing to build.func documentation: +1. Update relevant documentation files +2. Add examples for new features +3. Update architecture diagrams if needed +4. Test all examples before submitting +5. Follow the existing documentation style + +## Related Documentation + +- [Main README](../../README.md) - Project overview +- [Installation Guide](../../install/) - Installation scripts +- [Container Templates](../../ct/) - Container templates +- [Tools](../../tools/) - Additional tools and utilities + +## Support + +For issues and questions: +1. Check this documentation first +2. Review the [troubleshooting section](#troubleshooting) +3. Check existing issues in the project repository +4. Create a new issue with detailed information + +--- + +*Last updated: $(date)* +*Documentation version: 1.0* diff --git a/docs/misc/cloud-init.func/CLOUD_INIT_FUNC_FLOWCHART.md b/docs/misc/cloud-init.func/CLOUD_INIT_FUNC_FLOWCHART.md new file mode 100644 index 000000000..ad03c9438 --- /dev/null +++ b/docs/misc/cloud-init.func/CLOUD_INIT_FUNC_FLOWCHART.md @@ -0,0 +1,28 @@ +# cloud-init.func Flowchart + +Cloud-init VM provisioning flow. + +## Cloud-Init Generation and Application + +``` +generate_cloud_init() + ↓ +generate_user_data() + ↓ +setup_ssh_keys() + ↓ +Apply to VM + ↓ +VM Boot + ↓ +cloud-init phases +β”œβ”€ system +β”œβ”€ config +└─ final + ↓ +VM Ready βœ“ +``` + +--- + +**Last Updated**: December 2025 diff --git a/docs/misc/cloud-init.func/CLOUD_INIT_FUNC_FUNCTIONS_REFERENCE.md b/docs/misc/cloud-init.func/CLOUD_INIT_FUNC_FUNCTIONS_REFERENCE.md new file mode 100644 index 000000000..1ae2f44b9 --- /dev/null +++ b/docs/misc/cloud-init.func/CLOUD_INIT_FUNC_FUNCTIONS_REFERENCE.md @@ -0,0 +1,30 @@ +# cloud-init.func Functions Reference + +Cloud-init and VM provisioning functions. + +## Core Functions + +### generate_cloud_init() +Generate cloud-init configuration. + +### generate_user_data() +Generate user-data script for VM. + +### apply_cloud_init() +Apply cloud-init to VM. + +### setup_ssh_keys() +Deploy SSH public keys. + +### setup_static_ip() +Configure static IP on VM. + +### setup_dns() +Configure DNS for VM. + +### setup_ipv6() +Enable IPv6 on VM. + +--- + +**Last Updated**: December 2025 diff --git a/docs/misc/cloud-init.func/CLOUD_INIT_FUNC_INTEGRATION.md b/docs/misc/cloud-init.func/CLOUD_INIT_FUNC_INTEGRATION.md new file mode 100644 index 000000000..d494a4bed --- /dev/null +++ b/docs/misc/cloud-init.func/CLOUD_INIT_FUNC_INTEGRATION.md @@ -0,0 +1,7 @@ +# cloud-init.func Integration Guide + +Cloud-init integration with Proxmox VM provisioning. + +--- + +**Last Updated**: December 2025 diff --git a/docs/misc/cloud-init.func/CLOUD_INIT_FUNC_USAGE_EXAMPLES.md b/docs/misc/cloud-init.func/CLOUD_INIT_FUNC_USAGE_EXAMPLES.md new file mode 100644 index 000000000..13b6dacca --- /dev/null +++ b/docs/misc/cloud-init.func/CLOUD_INIT_FUNC_USAGE_EXAMPLES.md @@ -0,0 +1,17 @@ +# cloud-init.func Usage Examples + +Examples for VM cloud-init configuration. + +### Example: Basic Cloud-Init + +```bash +#!/usr/bin/env bash + +generate_cloud_init > cloud-init.yaml +setup_ssh_keys "$VMID" "$SSH_KEY" +apply_cloud_init "$VMID" cloud-init.yaml +``` + +--- + +**Last Updated**: December 2025 diff --git a/docs/misc/cloud-init.func/README.md b/docs/misc/cloud-init.func/README.md new file mode 100644 index 000000000..53450b4c2 --- /dev/null +++ b/docs/misc/cloud-init.func/README.md @@ -0,0 +1,339 @@ +# cloud-init.func Documentation + +## Overview + +The `cloud-init.func` file provides cloud-init configuration and VM initialization functions for Proxmox VE virtual machines. It handles user data, cloud-config generation, and VM setup automation. + +## Purpose and Use Cases + +- **VM Cloud-Init Setup**: Generate and apply cloud-init configurations for VMs +- **User Data Generation**: Create user-data scripts for VM initialization +- **Cloud-Config**: Generate cloud-config YAML for VM provisioning +- **SSH Key Management**: Setup SSH keys for VM access +- **Network Configuration**: Configure networking for VMs +- **Automated VM Provisioning**: Complete VM setup without manual intervention + +## Quick Reference + +### Key Function Groups +- **Cloud-Init Core**: Generate and apply cloud-init configurations +- **User Data**: Create initialization scripts for VMs +- **SSH Setup**: Deploy SSH keys automatically +- **Network Configuration**: Setup networking during VM provisioning +- **VM Customization**: Apply custom settings to VMs + +### Dependencies +- **External**: `cloud-init`, `curl`, `qemu-img` +- **Internal**: Uses functions from `core.func`, `error_handler.func` + +### Integration Points +- Used by: VM creation scripts (vm/*.sh) +- Uses: Environment variables from build.func +- Provides: VM initialization and cloud-init services + +## Documentation Files + +### πŸ“Š [CLOUD_INIT_FUNC_FLOWCHART.md](./CLOUD_INIT_FUNC_FLOWCHART.md) +Visual execution flows showing cloud-init generation and VM provisioning workflows. + +### πŸ“š [CLOUD_INIT_FUNC_FUNCTIONS_REFERENCE.md](./CLOUD_INIT_FUNC_FUNCTIONS_REFERENCE.md) +Complete alphabetical reference of all cloud-init functions. + +### πŸ’‘ [CLOUD_INIT_FUNC_USAGE_EXAMPLES.md](./CLOUD_INIT_FUNC_USAGE_EXAMPLES.md) +Practical examples for VM cloud-init setup and customization. + +### πŸ”— [CLOUD_INIT_FUNC_INTEGRATION.md](./CLOUD_INIT_FUNC_INTEGRATION.md) +How cloud-init.func integrates with VM creation and Proxmox workflows. + +## Key Features + +### Cloud-Init Configuration +- **User Data Generation**: Create custom initialization scripts +- **Cloud-Config YAML**: Generate standardized cloud-config +- **SSH Keys**: Automatically deploy public keys +- **Package Installation**: Install packages during VM boot +- **Custom Commands**: Run arbitrary commands on first boot + +### VM Network Setup +- **DHCP Configuration**: Configure DHCP for automatic IP assignment +- **Static IP Setup**: Configure static IP addresses +- **IPv6 Support**: Enable IPv6 on VMs +- **DNS Configuration**: Set DNS servers for VM +- **Firewall Rules**: Basic firewall configuration + +### Security Features +- **SSH Key Injection**: Deploy SSH keys during VM creation +- **Disable Passwords**: Disable password authentication +- **Sudoers Configuration**: Setup sudo access +- **User Management**: Create and configure users + +## Function Categories + +### πŸ”Ή Cloud-Init Core Functions +- `generate_cloud_init()` - Create cloud-init configuration +- `generate_user_data()` - Generate user-data script +- `apply_cloud_init()` - Apply cloud-init to VM +- `validate_cloud_init()` - Validate cloud-config syntax + +### πŸ”Ή SSH & Security Functions +- `setup_ssh_keys()` - Deploy SSH public keys +- `setup_sudo()` - Configure sudoers +- `create_user()` - Create new user account +- `disable_password_auth()` - Disable password login + +### πŸ”Ή Network Configuration Functions +- `setup_dhcp()` - Configure DHCP networking +- `setup_static_ip()` - Configure static IP +- `setup_dns()` - Configure DNS servers +- `setup_ipv6()` - Enable IPv6 support + +### πŸ”Ή VM Customization Functions +- `install_packages()` - Install packages during boot +- `run_custom_commands()` - Execute custom scripts +- `configure_hostname()` - Set VM hostname +- `configure_timezone()` - Set VM timezone + +## Cloud-Init Workflow + +``` +VM Created + ↓ +cloud-init (system) boot phase + ↓ +User-Data Script Execution + ↓ +β”œβ”€ Install packages +β”œβ”€ Deploy SSH keys +β”œβ”€ Configure network +└─ Create users + ↓ +cloud-init config phase + ↓ +Apply cloud-config settings + ↓ +cloud-init final phase + ↓ +VM Ready for Use +``` + +## Common Usage Patterns + +### Basic VM Setup with Cloud-Init +```bash +#!/usr/bin/env bash +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" + +# Generate cloud-init configuration +cat > cloud-init.yaml < user-data.txt + +# Inject SSH key +setup_ssh_keys "$VMID" "$SSH_KEY" + +# Create VM with cloud-init +qm create $VMID ... --cicustom local:snippets/user-data +``` + +### Network Configuration +```bash +#!/usr/bin/env bash +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" + +# Static IP setup +setup_static_ip "192.168.1.100" "255.255.255.0" "192.168.1.1" + +# DNS configuration +setup_dns "8.8.8.8 8.8.4.4" + +# IPv6 support +setup_ipv6 +``` + +## Best Practices + +### βœ… DO +- Validate cloud-config syntax before applying +- Use cloud-init for automated setup +- Deploy SSH keys for secure access +- Test cloud-init configuration in non-production first +- Use DHCP for easier VM deployment +- Document custom cloud-init configurations +- Version control cloud-init templates + +### ❌ DON'T +- Use weak SSH keys or passwords +- Leave SSH password authentication enabled +- Hardcode credentials in cloud-init +- Skip validation of cloud-config +- Use untrusted cloud-init sources +- Forget to set timezone on VMs +- Mix cloud-init versions + +## Cloud-Config Format + +### Example Cloud-Config +```yaml +#cloud-config +# This is a comment + +# System configuration +hostname: myvm +timezone: UTC +package_upgrade: true + +# Packages to install +packages: + - curl + - wget + - git + - build-essential + +# SSH keys for users +ssh_authorized_keys: + - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC... + +# Users to create +users: + - name: ubuntu + home: /home/ubuntu + shell: /bin/bash + sudo: ['ALL=(ALL) NOPASSWD:ALL'] + ssh_authorized_keys: + - ssh-rsa AAAAB3... + +# Commands to run on boot +runcmd: + - apt-get update + - apt-get upgrade -y + - systemctl restart ssh + +# Files to create +write_files: + - path: /etc/profile.d/custom.sh + content: | + export CUSTOM_VAR="value" +``` + +## VM Network Configuration + +### DHCP Configuration +```bash +network: + version: 2 + ethernets: + eth0: + dhcp4: true + dhcp6: true +``` + +### Static IP Configuration +```bash +network: + version: 2 + ethernets: + eth0: + addresses: + - 192.168.1.100/24 + gateway4: 192.168.1.1 + nameservers: + addresses: [8.8.8.8, 8.8.4.4] +``` + +## Troubleshooting + +### "Cloud-Init Configuration Not Applied" +```bash +# Check cloud-init status in VM +cloud-init status +cloud-init status --long + +# View cloud-init logs +tail /var/log/cloud-init.log +``` + +### "SSH Keys Not Deployed" +```bash +# Verify SSH key in cloud-config +grep ssh_authorized_keys user-data.txt + +# Check permissions +ls -la ~/.ssh/authorized_keys +``` + +### "Network Not Configured" +```bash +# Check network configuration +ip addr show +ip route show + +# View netplan (if used) +cat /etc/netplan/*.yaml +``` + +### "Packages Failed to Install" +```bash +# Check cloud-init package log +tail /var/log/cloud-init-output.log + +# Manual package installation +apt-get update && apt-get install -y package-name +``` + +## Related Documentation + +- **[install.func/](../install.func/)** - Container installation (similar workflow) +- **[core.func/](../core.func/)** - Utility functions +- **[error_handler.func/](../error_handler.func/)** - Error handling +- **[UPDATED_APP-install.md](../../UPDATED_APP-install.md)** - Application setup guide +- **Proxmox Docs**: https://pve.proxmox.com/wiki/Cloud-Init + +## Recent Updates + +### Version 2.0 (Dec 2025) +- βœ… Enhanced cloud-init validation +- βœ… Improved SSH key deployment +- βœ… Better network configuration support +- βœ… Added IPv6 support +- βœ… Streamlined user and package setup + +--- + +**Last Updated**: December 2025 +**Maintainers**: community-scripts team +**License**: MIT diff --git a/docs/misc/core.func/CORE_FLOWCHART.md b/docs/misc/core.func/CORE_FLOWCHART.md new file mode 100644 index 000000000..2b9dd98ce --- /dev/null +++ b/docs/misc/core.func/CORE_FLOWCHART.md @@ -0,0 +1,316 @@ +# core.func Execution Flowchart + +## Main Execution Flow + +``` +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ core.func Loading β”‚ +β”‚ Entry point when core.func is sourced by other scripts β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ Load Prevention Check β”‚ +β”‚ β€’ Check if _CORE_FUNC_LOADED is set β”‚ +β”‚ β€’ Return early if already loaded β”‚ +β”‚ β€’ Set _CORE_FUNC_LOADED=1 to prevent reloading β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ LOAD_FUNCTIONS() β”‚ +β”‚ Main function loader - sets up all core utilities β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ Core Function Loading Sequence β”‚ +β”‚ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ color() β”‚ β”‚ formatting() β”‚ β”‚ icons() β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β€’ Set ANSI β”‚ β”‚ β€’ Set format β”‚ β”‚ β€’ Set symbolic icons β”‚ β”‚ +β”‚ β”‚ color codes β”‚ β”‚ helpers β”‚ β”‚ β€’ Define message β”‚ β”‚ +β”‚ β”‚ β€’ Define β”‚ β”‚ β€’ Tab, bold, β”‚ β”‚ symbols β”‚ β”‚ +β”‚ β”‚ colors β”‚ β”‚ line reset β”‚ β”‚ β€’ Status indicators β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β”‚ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ default_vars() β”‚ β”‚ set_std_mode() β”‚ β”‚ Additional Functions β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β€’ Set retry β”‚ β”‚ β€’ Set verbose β”‚ β”‚ β€’ Add more functions β”‚ β”‚ +β”‚ β”‚ variables β”‚ β”‚ mode β”‚ β”‚ as needed β”‚ β”‚ +β”‚ β”‚ β€’ Initialize β”‚ β”‚ β€’ Configure β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ counters β”‚ β”‚ STD variable β”‚ β”‚ β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +``` + +## System Check Functions Flow + +``` +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ System Validation Flow β”‚ +β”‚ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ PVE_CHECK() β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ +β”‚ β”‚ β”‚ Get PVE β”‚ β”‚ Check PVE β”‚ β”‚ Check PVE β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ Version β”‚ β”‚ 8.x Support β”‚ β”‚ 9.x Support β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ pveversion β”‚ β”‚ β€’ Allow 8.0-8.9β”‚ β”‚ β€’ Allow ONLY 9.0 β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ Parse version β”‚ β”‚ β€’ Reject others β”‚ β”‚ β€’ Reject 9.1+ β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ Extract β”‚ β”‚ β€’ Exit if β”‚ β”‚ β€’ Exit if β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ major.minor β”‚ β”‚ unsupported β”‚ β”‚ unsupported β”‚ β”‚ β”‚ +β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β”‚ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ ARCH_CHECK() β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ +β”‚ β”‚ β”‚ Check β”‚ β”‚ AMD64 Check β”‚ β”‚ PiMox Warning β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ Architecture β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ β€’ dpkg --print- β”‚ β”‚ β€’ Show PiMox β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ Get system β”‚ β”‚ architecture β”‚ β”‚ message β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ architecture β”‚ β”‚ β€’ Must be β”‚ β”‚ β€’ Point to ARM64 β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ Compare with β”‚ β”‚ "amd64" β”‚ β”‚ support β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ "amd64" β”‚ β”‚ β€’ Exit if not β”‚ β”‚ β€’ Exit script β”‚ β”‚ β”‚ +β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β”‚ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ SHELL_CHECK() β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ +β”‚ β”‚ β”‚ Check β”‚ β”‚ Bash Check β”‚ β”‚ Error Handling β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ Shell Type β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ β€’ ps -p $$ -o β”‚ β”‚ β€’ Clear screen β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ Get current β”‚ β”‚ comm= β”‚ β”‚ β€’ Show error β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ shell β”‚ β”‚ β€’ Must be β”‚ β”‚ β€’ Sleep and exit β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ Compare with β”‚ β”‚ "bash" β”‚ β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ "bash" β”‚ β”‚ β€’ Exit if not β”‚ β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β”‚ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ ROOT_CHECK() β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ +β”‚ β”‚ β”‚ Check β”‚ β”‚ Root Check β”‚ β”‚ Sudo Check β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ User ID β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ β€’ id -u β”‚ β”‚ β€’ Check parent β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ Get user ID β”‚ β”‚ β€’ Must be 0 β”‚ β”‚ process β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ Check if β”‚ β”‚ β€’ Exit if not β”‚ β”‚ β€’ Detect sudo β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ root (0) β”‚ β”‚ root β”‚ β”‚ usage β”‚ β”‚ β”‚ +β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +``` + +## Message System Flow + +``` +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ Message System Flow β”‚ +β”‚ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ MSG_INFO() β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ +β”‚ β”‚ β”‚ Message β”‚ β”‚ Duplicate β”‚ β”‚ Display Mode β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ Validation β”‚ β”‚ Check β”‚ β”‚ Selection β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ Check if β”‚ β”‚ β€’ Track shown β”‚ β”‚ β€’ Verbose mode: β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ message β”‚ β”‚ messages β”‚ β”‚ Show directly β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ exists β”‚ β”‚ β€’ Skip if β”‚ β”‚ β€’ Normal mode: β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ Return if β”‚ β”‚ already β”‚ β”‚ Start spinner β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ empty β”‚ β”‚ shown β”‚ β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β”‚ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ SPINNER() β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ +β”‚ β”‚ β”‚ Spinner β”‚ β”‚ Animation β”‚ β”‚ Display β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ Initializationβ”‚ β”‚ Loop β”‚ β”‚ Control β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ Define β”‚ β”‚ β€’ Cycle through β”‚ β”‚ β€’ Print spinner β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ characters β”‚ β”‚ characters β”‚ β”‚ character β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ Set index β”‚ β”‚ β€’ Sleep 0.1s β”‚ β”‚ β€’ Print message β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ Start loop β”‚ β”‚ β€’ Increment β”‚ β”‚ β€’ Clear line β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ index β”‚ β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β”‚ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ STOP_SPINNER() β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ +β”‚ β”‚ β”‚ Get Spinner β”‚ β”‚ Kill Process β”‚ β”‚ Cleanup β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ PID β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ β€’ Send TERM β”‚ β”‚ β€’ Remove PID file β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ From β”‚ β”‚ β€’ Wait for β”‚ β”‚ β€’ Unset variables β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ SPINNER_PID β”‚ β”‚ termination β”‚ β”‚ β€’ Reset terminal β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ From PID β”‚ β”‚ β€’ Force kill β”‚ β”‚ settings β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ file β”‚ β”‚ if needed β”‚ β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +``` + +## Silent Execution Flow + +``` +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ SILENT() Execution Flow β”‚ +β”‚ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ Command Execution β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ +β”‚ β”‚ β”‚ Setup β”‚ β”‚ Execute β”‚ β”‚ Capture Output β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ Environment β”‚ β”‚ Command β”‚ β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β€’ Redirect stdout β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ Disable β”‚ β”‚ β€’ Run command β”‚ β”‚ to log file β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ error β”‚ β”‚ β€’ Capture β”‚ β”‚ β€’ Redirect stderr β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ handling β”‚ β”‚ return code β”‚ β”‚ to log file β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ Remove β”‚ β”‚ β€’ Store exit β”‚ β”‚ β€’ Log all output β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ traps β”‚ β”‚ code β”‚ β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β”‚ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ Error Handling β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ +β”‚ β”‚ β”‚ Check Exit β”‚ β”‚ Load Error β”‚ β”‚ Display Error β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ Code β”‚ β”‚ Handler β”‚ β”‚ Information β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ If exit code β”‚ β”‚ β€’ Source β”‚ β”‚ β€’ Show error code β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ != 0 β”‚ β”‚ error_handler β”‚ β”‚ β€’ Show explanation β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ Proceed to β”‚ β”‚ if needed β”‚ β”‚ β€’ Show command β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ error β”‚ β”‚ β€’ Get error β”‚ β”‚ β€’ Show log lines β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ handling β”‚ β”‚ explanation β”‚ β”‚ β€’ Show full log β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ command β”‚ β”‚ β”‚ +β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β”‚ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ Log Management β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ +β”‚ β”‚ β”‚ Log File β”‚ β”‚ Log Display β”‚ β”‚ Log Access β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ Management β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ β€’ Show last 10 β”‚ β”‚ β€’ Provide command β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ Create log β”‚ β”‚ lines β”‚ β”‚ to view full log β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ file path β”‚ β”‚ β€’ Count total β”‚ β”‚ β€’ Show line count β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ Use process β”‚ β”‚ lines β”‚ β”‚ β€’ Enable debugging β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ ID in name β”‚ β”‚ β€’ Format β”‚ β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ output β”‚ β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +``` + +## Header Management Flow + +``` +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ Header Management Flow β”‚ +β”‚ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ GET_HEADER() β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ +β”‚ β”‚ β”‚ Prepare β”‚ β”‚ Check Local β”‚ β”‚ Download Header β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ Parameters β”‚ β”‚ File β”‚ β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β€’ Construct URL β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ Get app name β”‚ β”‚ β€’ Check if β”‚ β”‚ β€’ Download file β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ from APP β”‚ β”‚ file exists β”‚ β”‚ β€’ Save to local β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ Get app type β”‚ β”‚ β€’ Check if β”‚ β”‚ path β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ from APP_TYPE β”‚ β”‚ file has β”‚ β”‚ β€’ Return success β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ Construct β”‚ β”‚ content β”‚ β”‚ status β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ paths β”‚ β”‚ β€’ Return if β”‚ β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ available β”‚ β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β”‚ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ HEADER_INFO() β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ +β”‚ β”‚ β”‚ Get Header β”‚ β”‚ Clear Screen β”‚ β”‚ Display Header β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ Content β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ β€’ Clear β”‚ β”‚ β€’ Show header β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ Call β”‚ β”‚ terminal β”‚ β”‚ content if β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ get_header() β”‚ β”‚ β€’ Get terminal β”‚ β”‚ available β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ Handle β”‚ β”‚ width β”‚ β”‚ β€’ Format output β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ errors β”‚ β”‚ β€’ Set default β”‚ β”‚ β€’ Center content β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ Return β”‚ β”‚ width if β”‚ β”‚ if possible β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ content β”‚ β”‚ needed β”‚ β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +``` + +## Swap Management Flow + +``` +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ CHECK_OR_CREATE_SWAP() Flow β”‚ +β”‚ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ Swap Detection β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ +β”‚ β”‚ β”‚ Check Active β”‚ β”‚ Swap Found β”‚ β”‚ No Swap Found β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ Swap β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ β€’ Show success β”‚ β”‚ β€’ Show error β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ Use swapon β”‚ β”‚ message β”‚ β”‚ message β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ command β”‚ β”‚ β€’ Return 0 β”‚ β”‚ β€’ Ask user for β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ Check for β”‚ β”‚ β”‚ β”‚ creation β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ swap devices β”‚ β”‚ β”‚ β”‚ β€’ Proceed to β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ Return β”‚ β”‚ β”‚ β”‚ creation flow β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ status β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β”‚ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ Swap Creation β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ +β”‚ β”‚ β”‚ User Input β”‚ β”‚ Size β”‚ β”‚ File Creation β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ Collection β”‚ β”‚ Validation β”‚ β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β€’ Create swap file β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ Ask for β”‚ β”‚ β€’ Validate β”‚ β”‚ with dd β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ confirmation β”‚ β”‚ numeric input β”‚ β”‚ β€’ Set permissions β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ Convert to β”‚ β”‚ β€’ Check range β”‚ β”‚ β€’ Format swap β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ lowercase β”‚ β”‚ β€’ Abort if β”‚ β”‚ β€’ Activate swap β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ Check for β”‚ β”‚ invalid β”‚ β”‚ β€’ Show success β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ y/yes β”‚ β”‚ β”‚ β”‚ message β”‚ β”‚ β”‚ +β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +``` + +## Integration Points + +### With Other Scripts +- **build.func**: Provides system checks and UI functions +- **tools.func**: Uses core utilities for extended operations +- **api.func**: Uses system checks and error handling +- **error_handler.func**: Provides error explanations for silent execution + +### External Dependencies +- **curl**: For downloading header files +- **tput**: For terminal control (installed if missing) +- **swapon/mkswap**: For swap management +- **pveversion**: For Proxmox version checking + +### Data Flow +- **Input**: Environment variables, command parameters +- **Processing**: System validation, UI rendering, command execution +- **Output**: Messages, log files, exit codes, system state changes diff --git a/docs/misc/core.func/CORE_FUNCTIONS_REFERENCE.md b/docs/misc/core.func/CORE_FUNCTIONS_REFERENCE.md new file mode 100644 index 000000000..1dacb1609 --- /dev/null +++ b/docs/misc/core.func/CORE_FUNCTIONS_REFERENCE.md @@ -0,0 +1,637 @@ +# core.func Functions Reference + +## Overview + +This document provides a comprehensive alphabetical reference of all functions in `core.func`, including parameters, dependencies, usage examples, and error handling. + +## Function Categories + +### Initialization Functions + +#### `load_functions()` +**Purpose**: Main function loader that initializes all core utilities +**Parameters**: None +**Returns**: None +**Side Effects**: +- Sets `__FUNCTIONS_LOADED=1` to prevent reloading +- Calls all core function groups in sequence +- Initializes color, formatting, icons, defaults, and standard mode +**Dependencies**: None +**Environment Variables Used**: `__FUNCTIONS_LOADED` + +**Usage Example**: +```bash +# Automatically called when core.func is sourced +source core.func +# load_functions() is called automatically +``` + +### Color and Formatting Functions + +#### `color()` +**Purpose**: Set ANSI color codes for styled terminal output +**Parameters**: None +**Returns**: None +**Side Effects**: Sets global color variables +**Dependencies**: None +**Environment Variables Used**: None + +**Sets Variables**: +- `YW`: Yellow +- `YWB`: Bright yellow +- `BL`: Blue +- `RD`: Red +- `BGN`: Bright green +- `GN`: Green +- `DGN`: Dark green +- `CL`: Clear/reset + +**Usage Example**: +```bash +color +echo -e "${GN}Success message${CL}" +echo -e "${RD}Error message${CL}" +``` + +#### `color_spinner()` +**Purpose**: Set color codes specifically for spinner output +**Parameters**: None +**Returns**: None +**Side Effects**: Sets spinner-specific color variables +**Dependencies**: None +**Environment Variables Used**: None + +**Sets Variables**: +- `CS_YW`: Yellow for spinner +- `CS_YWB`: Bright yellow for spinner +- `CS_CL`: Clear for spinner + +#### `formatting()` +**Purpose**: Define formatting helpers for terminal output +**Parameters**: None +**Returns**: None +**Side Effects**: Sets global formatting variables +**Dependencies**: None +**Environment Variables Used**: None + +**Sets Variables**: +- `BFR`: Back and forward reset +- `BOLD`: Bold text +- `HOLD`: Space character +- `TAB`: Two spaces +- `TAB3`: Six spaces + +### Icon Functions + +#### `icons()` +**Purpose**: Set symbolic icons used throughout user feedback and prompts +**Parameters**: None +**Returns**: None +**Side Effects**: Sets global icon variables +**Dependencies**: `formatting()` (for TAB variable) +**Environment Variables Used**: `TAB`, `CL` + +**Sets Variables**: +- `CM`: Check mark +- `CROSS`: Cross mark +- `DNSOK`: DNS success +- `DNSFAIL`: DNS failure +- `INFO`: Information icon +- `OS`: Operating system icon +- `OSVERSION`: OS version icon +- `CONTAINERTYPE`: Container type icon +- `DISKSIZE`: Disk size icon +- `CPUCORE`: CPU core icon +- `RAMSIZE`: RAM size icon +- `SEARCH`: Search icon +- `VERBOSE_CROPPED`: Verbose mode icon +- `VERIFYPW`: Password verification icon +- `CONTAINERID`: Container ID icon +- `HOSTNAME`: Hostname icon +- `BRIDGE`: Bridge icon +- `NETWORK`: Network icon +- `GATEWAY`: Gateway icon +- `DISABLEIPV6`: IPv6 disable icon +- `DEFAULT`: Default settings icon +- `MACADDRESS`: MAC address icon +- `VLANTAG`: VLAN tag icon +- `ROOTSSH`: SSH key icon +- `CREATING`: Creating icon +- `ADVANCED`: Advanced settings icon +- `FUSE`: FUSE icon +- `HOURGLASS`: Hourglass icon + +### Default Variables Functions + +#### `default_vars()` +**Purpose**: Set default retry and wait variables for system actions +**Parameters**: None +**Returns**: None +**Side Effects**: Sets retry configuration variables +**Dependencies**: None +**Environment Variables Used**: None + +**Sets Variables**: +- `RETRY_NUM`: Number of retry attempts (default: 10) +- `RETRY_EVERY`: Seconds between retries (default: 3) +- `i`: Retry counter initialized to RETRY_NUM + +#### `set_std_mode()` +**Purpose**: Set default verbose mode for script execution +**Parameters**: None +**Returns**: None +**Side Effects**: Sets STD variable based on VERBOSE setting +**Dependencies**: None +**Environment Variables Used**: `VERBOSE` + +**Sets Variables**: +- `STD`: "silent" if VERBOSE != "yes", empty string if VERBOSE = "yes" + +### Silent Execution Functions + +#### `silent()` +**Purpose**: Execute commands silently with detailed error reporting +**Parameters**: `$*` - Command and arguments to execute +**Returns**: None (exits on error) +**Side Effects**: +- Executes command with output redirected to log file +- On error, displays detailed error information +- Exits with command's exit code +**Dependencies**: `error_handler.func` (for error explanations) +**Environment Variables Used**: `SILENT_LOGFILE` + +**Usage Example**: +```bash +silent apt-get update +silent apt-get install -y package-name +``` + +**Error Handling**: +- Captures command output to `/tmp/silent.$$.log` +- Shows error code explanation +- Displays last 10 lines of log +- Provides command to view full log + +### System Check Functions + +#### `shell_check()` +**Purpose**: Verify that the script is running in Bash shell +**Parameters**: None +**Returns**: None (exits if not Bash) +**Side Effects**: +- Checks current shell process +- Exits with error message if not Bash +**Dependencies**: None +**Environment Variables Used**: None + +**Usage Example**: +```bash +shell_check +# Script continues if Bash, exits if not +``` + +#### `root_check()` +**Purpose**: Ensure script is running as root user +**Parameters**: None +**Returns**: None (exits if not root) +**Side Effects**: +- Checks user ID and parent process +- Exits with error message if not root +**Dependencies**: None +**Environment Variables Used**: None + +**Usage Example**: +```bash +root_check +# Script continues if root, exits if not +``` + +#### `pve_check()` +**Purpose**: Verify Proxmox VE version compatibility +**Parameters**: None +**Returns**: None (exits if unsupported version) +**Side Effects**: +- Checks PVE version using pveversion command +- Exits with error message if unsupported +**Dependencies**: `pveversion` command +**Environment Variables Used**: None + +**Supported Versions**: +- Proxmox VE 8.0 - 8.9 +- Proxmox VE 9.0 (only) + +**Usage Example**: +```bash +pve_check +# Script continues if supported version, exits if not +``` + +#### `arch_check()` +**Purpose**: Verify system architecture is AMD64 +**Parameters**: None +**Returns**: None (exits if not AMD64) +**Side Effects**: +- Checks system architecture +- Exits with PiMox warning if not AMD64 +**Dependencies**: `dpkg` command +**Environment Variables Used**: None + +**Usage Example**: +```bash +arch_check +# Script continues if AMD64, exits if not +``` + +#### `ssh_check()` +**Purpose**: Detect and warn about external SSH usage +**Parameters**: None +**Returns**: None +**Side Effects**: +- Checks SSH_CLIENT environment variable +- Warns if connecting from external IP +- Allows local connections (127.0.0.1 or host IP) +**Dependencies**: None +**Environment Variables Used**: `SSH_CLIENT` + +**Usage Example**: +```bash +ssh_check +# Shows warning if external SSH, continues anyway +``` + +### Header Management Functions + +#### `get_header()` +**Purpose**: Download and cache application header files +**Parameters**: None (uses APP and APP_TYPE variables) +**Returns**: Header content on success, empty on failure +**Side Effects**: +- Downloads header from remote URL +- Caches header locally +- Creates directory structure if needed +**Dependencies**: `curl` command +**Environment Variables Used**: `APP`, `APP_TYPE` + +**Usage Example**: +```bash +export APP="plex" +export APP_TYPE="ct" +header_content=$(get_header) +``` + +#### `header_info()` +**Purpose**: Display application header information +**Parameters**: None (uses APP variable) +**Returns**: None +**Side Effects**: +- Clears screen +- Displays header content +- Gets terminal width for formatting +**Dependencies**: `get_header()`, `tput` command +**Environment Variables Used**: `APP` + +**Usage Example**: +```bash +export APP="plex" +header_info +# Displays Plex header information +``` + +### Utility Functions + +#### `ensure_tput()` +**Purpose**: Ensure tput command is available for terminal control +**Parameters**: None +**Returns**: None +**Side Effects**: +- Installs ncurses package if tput missing +- Works on Alpine and Debian-based systems +**Dependencies**: `apk` or `apt-get` package managers +**Environment Variables Used**: None + +**Usage Example**: +```bash +ensure_tput +# Installs ncurses if needed, continues if already available +``` + +#### `is_alpine()` +**Purpose**: Detect if running on Alpine Linux +**Parameters**: None +**Returns**: 0 if Alpine, 1 if not Alpine +**Side Effects**: None +**Dependencies**: None +**Environment Variables Used**: `var_os`, `PCT_OSTYPE` + +**Usage Example**: +```bash +if is_alpine; then + echo "Running on Alpine Linux" +else + echo "Not running on Alpine Linux" +fi +``` + +#### `is_verbose_mode()` +**Purpose**: Check if verbose mode is enabled +**Parameters**: None +**Returns**: 0 if verbose mode, 1 if not verbose +**Side Effects**: None +**Dependencies**: None +**Environment Variables Used**: `VERBOSE`, `var_verbose` + +**Usage Example**: +```bash +if is_verbose_mode; then + echo "Verbose mode enabled" +else + echo "Verbose mode disabled" +fi +``` + +#### `fatal()` +**Purpose**: Display fatal error and terminate script +**Parameters**: `$1` - Error message +**Returns**: None (terminates script) +**Side Effects**: +- Displays error message +- Sends INT signal to current process +**Dependencies**: `msg_error()` +**Environment Variables Used**: None + +**Usage Example**: +```bash +fatal "Critical error occurred" +# Script terminates after displaying error +``` + +### Spinner Functions + +#### `spinner()` +**Purpose**: Display animated spinner for progress indication +**Parameters**: None (uses SPINNER_MSG variable) +**Returns**: None (runs indefinitely) +**Side Effects**: +- Displays rotating spinner characters +- Uses terminal control sequences +**Dependencies**: `color_spinner()` +**Environment Variables Used**: `SPINNER_MSG` + +**Usage Example**: +```bash +SPINNER_MSG="Processing..." +spinner & +SPINNER_PID=$! +# Spinner runs in background +``` + +#### `clear_line()` +**Purpose**: Clear current terminal line +**Parameters**: None +**Returns**: None +**Side Effects**: Clears current line using terminal control +**Dependencies**: `tput` command +**Environment Variables Used**: None + +#### `stop_spinner()` +**Purpose**: Stop running spinner and cleanup +**Parameters**: None +**Returns**: None +**Side Effects**: +- Kills spinner process +- Removes PID file +- Resets terminal settings +- Unsets spinner variables +**Dependencies**: None +**Environment Variables Used**: `SPINNER_PID`, `SPINNER_MSG` + +**Usage Example**: +```bash +stop_spinner +# Stops spinner and cleans up +``` + +### Message Functions + +#### `msg_info()` +**Purpose**: Display informational message with spinner +**Parameters**: `$1` - Message text +**Returns**: None +**Side Effects**: +- Starts spinner if not in verbose mode +- Tracks shown messages to prevent duplicates +- Displays message with hourglass icon in verbose mode +**Dependencies**: `spinner()`, `is_verbose_mode()`, `is_alpine()` +**Environment Variables Used**: `MSG_INFO_SHOWN` + +**Usage Example**: +```bash +msg_info "Installing package..." +# Shows spinner with message +``` + +#### `msg_ok()` +**Purpose**: Display success message +**Parameters**: `$1` - Success message text +**Returns**: None +**Side Effects**: +- Stops spinner +- Displays green checkmark with message +- Removes message from shown tracking +**Dependencies**: `stop_spinner()` +**Environment Variables Used**: `MSG_INFO_SHOWN` + +**Usage Example**: +```bash +msg_ok "Package installed successfully" +# Shows green checkmark with message +``` + +#### `msg_error()` +**Purpose**: Display error message +**Parameters**: `$1` - Error message text +**Returns**: None +**Side Effects**: +- Stops spinner +- Displays red cross with message +**Dependencies**: `stop_spinner()` +**Environment Variables Used**: None + +**Usage Example**: +```bash +msg_error "Installation failed" +# Shows red cross with message +``` + +#### `msg_warn()` +**Purpose**: Display warning message +**Parameters**: `$1` - Warning message text +**Returns**: None +**Side Effects**: +- Stops spinner +- Displays yellow info icon with message +**Dependencies**: `stop_spinner()` +**Environment Variables Used**: None + +**Usage Example**: +```bash +msg_warn "This operation may take some time" +# Shows yellow info icon with message +``` + +#### `msg_custom()` +**Purpose**: Display custom message with specified symbol and color +**Parameters**: +- `$1` - Custom symbol (default: "[*]") +- `$2` - Color code (default: "\e[36m") +- `$3` - Message text +**Returns**: None +**Side Effects**: +- Stops spinner +- Displays custom formatted message +**Dependencies**: `stop_spinner()` +**Environment Variables Used**: None + +**Usage Example**: +```bash +msg_custom "⚑" "\e[33m" "Custom warning message" +# Shows custom symbol and color with message +``` + +#### `msg_debug()` +**Purpose**: Display debug message if debug mode enabled +**Parameters**: `$*` - Debug message text +**Returns**: None +**Side Effects**: +- Only displays if var_full_verbose is set +- Shows timestamp and debug prefix +**Dependencies**: None +**Environment Variables Used**: `var_full_verbose`, `var_verbose` + +**Usage Example**: +```bash +export var_full_verbose=1 +msg_debug "Debug information here" +# Shows debug message with timestamp +``` + +### System Management Functions + +#### `check_or_create_swap()` +**Purpose**: Check for active swap and optionally create swap file +**Parameters**: None +**Returns**: 0 if swap exists or created, 1 if skipped +**Side Effects**: +- Checks for active swap +- Prompts user to create swap if none found +- Creates swap file if user confirms +**Dependencies**: `swapon`, `dd`, `mkswap` commands +**Environment Variables Used**: None + +**Usage Example**: +```bash +if check_or_create_swap; then + echo "Swap is available" +else + echo "No swap available" +fi +``` + +## Function Call Hierarchy + +### Initialization Flow +``` +load_functions() +β”œβ”€β”€ color() +β”œβ”€β”€ formatting() +β”œβ”€β”€ icons() +β”œβ”€β”€ default_vars() +└── set_std_mode() +``` + +### Message System Flow +``` +msg_info() +β”œβ”€β”€ is_verbose_mode() +β”œβ”€β”€ is_alpine() +β”œβ”€β”€ spinner() +└── color_spinner() + +msg_ok() +β”œβ”€β”€ stop_spinner() +└── clear_line() + +msg_error() +└── stop_spinner() + +msg_warn() +└── stop_spinner() +``` + +### System Check Flow +``` +pve_check() +β”œβ”€β”€ pveversion command +└── version parsing + +arch_check() +β”œβ”€β”€ dpkg command +└── architecture check + +shell_check() +β”œβ”€β”€ ps command +└── shell detection + +root_check() +β”œβ”€β”€ id command +└── parent process check +``` + +### Silent Execution Flow +``` +silent() +β”œβ”€β”€ Command execution +β”œβ”€β”€ Output redirection +β”œβ”€β”€ Error handling +β”œβ”€β”€ error_handler.func loading +└── Log management +``` + +## Error Handling Patterns + +### System Check Errors +- All system check functions exit with appropriate error messages +- Clear indication of what's wrong and how to fix it +- Graceful exit with sleep delay for user to read message + +### Silent Execution Errors +- Commands executed via `silent()` capture output to log file +- On failure, displays error code explanation +- Shows last 10 lines of log output +- Provides command to view full log + +### Spinner Errors +- Spinner functions handle process cleanup on exit +- Trap handlers ensure spinners are stopped +- Terminal settings are restored on error + +## Environment Variable Dependencies + +### Required Variables +- `APP`: Application name for header display +- `APP_TYPE`: Application type (ct/vm) for header paths +- `VERBOSE`: Verbose mode setting + +### Optional Variables +- `var_os`: OS type for Alpine detection +- `PCT_OSTYPE`: Alternative OS type variable +- `var_verbose`: Alternative verbose setting +- `var_full_verbose`: Debug mode setting + +### Internal Variables +- `_CORE_FUNC_LOADED`: Prevents multiple loading +- `__FUNCTIONS_LOADED`: Prevents multiple function loading +- `SILENT_LOGFILE`: Silent execution log file path +- `SPINNER_PID`: Spinner process ID +- `SPINNER_MSG`: Spinner message text +- `MSG_INFO_SHOWN`: Tracks shown info messages diff --git a/docs/misc/core.func/CORE_INTEGRATION.md b/docs/misc/core.func/CORE_INTEGRATION.md new file mode 100644 index 000000000..b203f1c73 --- /dev/null +++ b/docs/misc/core.func/CORE_INTEGRATION.md @@ -0,0 +1,517 @@ +# core.func Integration Guide + +## Overview + +This document describes how `core.func` integrates with other components in the Proxmox Community Scripts project, including dependencies, data flow, and API surface. + +## Dependencies + +### External Dependencies + +#### Required Commands +- **`pveversion`**: Proxmox VE version checking +- **`dpkg`**: Architecture detection +- **`ps`**: Process and shell detection +- **`id`**: User ID checking +- **`curl`**: Header file downloading +- **`swapon`**: Swap status checking +- **`dd`**: Swap file creation +- **`mkswap`**: Swap file formatting + +#### Optional Commands +- **`tput`**: Terminal control (installed if missing) +- **`apk`**: Alpine package manager +- **`apt-get`**: Debian package manager + +### Internal Dependencies + +#### error_handler.func +- **Purpose**: Provides error code explanations for silent execution +- **Usage**: Automatically loaded when `silent()` encounters errors +- **Integration**: Called via `explain_exit_code()` function +- **Data Flow**: Error code β†’ explanation β†’ user display + +## Integration Points + +### With build.func + +#### System Validation +```bash +# build.func uses core.func for system checks +source core.func +pve_check +arch_check +shell_check +root_check +``` + +#### User Interface +```bash +# build.func uses core.func for UI elements +msg_info "Creating container..." +msg_ok "Container created successfully" +msg_error "Container creation failed" +``` + +#### Silent Execution +```bash +# build.func uses core.func for command execution +silent pct create "$CTID" "$TEMPLATE" \ + --hostname "$HOSTNAME" \ + --memory "$MEMORY" \ + --cores "$CORES" +``` + +### With tools.func + +#### Utility Functions +```bash +# tools.func uses core.func utilities +source core.func + +# System checks +pve_check +root_check + +# UI elements +msg_info "Running maintenance tasks..." +msg_ok "Maintenance completed" +``` + +#### Error Handling +```bash +# tools.func uses core.func for error handling +if silent systemctl restart service; then + msg_ok "Service restarted" +else + msg_error "Service restart failed" +fi +``` + +### With api.func + +#### System Validation +```bash +# api.func uses core.func for system checks +source core.func +pve_check +root_check +``` + +#### API Operations +```bash +# api.func uses core.func for API calls +msg_info "Connecting to Proxmox API..." +if silent curl -k -H "Authorization: PVEAPIToken=$API_TOKEN" \ + "$API_URL/api2/json/nodes/$NODE/lxc"; then + msg_ok "API connection successful" +else + msg_error "API connection failed" +fi +``` + +### With error_handler.func + +#### Error Explanations +```bash +# error_handler.func provides explanations for core.func +explain_exit_code() { + local code="$1" + case "$code" in + 1) echo "General error" ;; + 2) echo "Misuse of shell builtins" ;; + 126) echo "Command invoked cannot execute" ;; + 127) echo "Command not found" ;; + 128) echo "Invalid argument to exit" ;; + *) echo "Unknown error code" ;; + esac +} +``` + +### With install.func + +#### Installation Process +```bash +# install.func uses core.func for installation +source core.func + +# System checks +pve_check +root_check + +# Installation steps +msg_info "Installing packages..." +silent apt-get update +silent apt-get install -y package + +msg_ok "Installation completed" +``` + +### With alpine-install.func + +#### Alpine-Specific Operations +```bash +# alpine-install.func uses core.func for Alpine operations +source core.func + +# Alpine detection +if is_alpine; then + msg_info "Detected Alpine Linux" + silent apk add --no-cache package +else + msg_info "Detected Debian-based system" + silent apt-get install -y package +fi +``` + +### With alpine-tools.func + +#### Alpine Utilities +```bash +# alpine-tools.func uses core.func for Alpine tools +source core.func + +# Alpine-specific operations +if is_alpine; then + msg_info "Running Alpine-specific operations..." + # Alpine tools logic + msg_ok "Alpine operations completed" +fi +``` + +### With passthrough.func + +#### Hardware Passthrough +```bash +# passthrough.func uses core.func for hardware operations +source core.func + +# System checks +pve_check +root_check + +# Hardware operations +msg_info "Configuring GPU passthrough..." +if silent lspci | grep -i nvidia; then + msg_ok "NVIDIA GPU detected" +else + msg_warn "No NVIDIA GPU found" +fi +``` + +### With vm-core.func + +#### VM Operations +```bash +# vm-core.func uses core.func for VM management +source core.func + +# System checks +pve_check +root_check + +# VM operations +msg_info "Creating virtual machine..." +silent qm create "$VMID" \ + --name "$VMNAME" \ + --memory "$MEMORY" \ + --cores "$CORES" + +msg_ok "Virtual machine created" +``` + +## Data Flow + +### Input Data + +#### Environment Variables +- **`APP`**: Application name for header display +- **`APP_TYPE`**: Application type (ct/vm) for header paths +- **`VERBOSE`**: Verbose mode setting +- **`var_os`**: OS type for Alpine detection +- **`PCT_OSTYPE`**: Alternative OS type variable +- **`var_verbose`**: Alternative verbose setting +- **`var_full_verbose`**: Debug mode setting + +#### Command Parameters +- **Function arguments**: Passed to individual functions +- **Command arguments**: Passed to `silent()` function +- **User input**: Collected via `read` commands + +### Processing Data + +#### System Information +- **Proxmox version**: Parsed from `pveversion` output +- **Architecture**: Retrieved from `dpkg --print-architecture` +- **Shell type**: Detected from process information +- **User ID**: Retrieved from `id -u` +- **SSH connection**: Detected from `SSH_CLIENT` environment + +#### UI State +- **Message tracking**: `MSG_INFO_SHOWN` associative array +- **Spinner state**: `SPINNER_PID` and `SPINNER_MSG` variables +- **Terminal state**: Cursor position and display mode + +#### Error Information +- **Exit codes**: Captured from command execution +- **Log output**: Redirected to temporary log files +- **Error explanations**: Retrieved from error_handler.func + +### Output Data + +#### User Interface +- **Colored messages**: ANSI color codes for terminal output +- **Icons**: Symbolic representations for different message types +- **Spinners**: Animated progress indicators +- **Formatted text**: Consistent message formatting + +#### System State +- **Exit codes**: Returned from functions +- **Log files**: Created for silent execution +- **Configuration**: Modified system settings +- **Process state**: Spinner processes and cleanup + +## API Surface + +### Public Functions + +#### System Validation +- **`pve_check()`**: Proxmox VE version validation +- **`arch_check()`**: Architecture validation +- **`shell_check()`**: Shell validation +- **`root_check()`**: Privilege validation +- **`ssh_check()`**: SSH connection warning + +#### User Interface +- **`msg_info()`**: Informational messages +- **`msg_ok()`**: Success messages +- **`msg_error()`**: Error messages +- **`msg_warn()`**: Warning messages +- **`msg_custom()`**: Custom messages +- **`msg_debug()`**: Debug messages + +#### Spinner Control +- **`spinner()`**: Start spinner animation +- **`stop_spinner()`**: Stop spinner and cleanup +- **`clear_line()`**: Clear current terminal line + +#### Silent Execution +- **`silent()`**: Execute commands with error handling + +#### Utility Functions +- **`is_alpine()`**: Alpine Linux detection +- **`is_verbose_mode()`**: Verbose mode detection +- **`fatal()`**: Fatal error handling +- **`ensure_tput()`**: Terminal control setup + +#### Header Management +- **`get_header()`**: Download application headers +- **`header_info()`**: Display header information + +#### System Management +- **`check_or_create_swap()`**: Swap file management + +### Internal Functions + +#### Initialization +- **`load_functions()`**: Function loader +- **`color()`**: Color setup +- **`formatting()`**: Formatting setup +- **`icons()`**: Icon setup +- **`default_vars()`**: Default variables +- **`set_std_mode()`**: Standard mode setup + +#### Color Management +- **`color_spinner()`**: Spinner colors + +### Global Variables + +#### Color Variables +- **`YW`**, **`YWB`**, **`BL`**, **`RD`**, **`BGN`**, **`GN`**, **`DGN`**, **`CL`**: Color codes +- **`CS_YW`**, **`CS_YWB`**, **`CS_CL`**: Spinner colors + +#### Formatting Variables +- **`BFR`**, **`BOLD`**, **`HOLD`**, **`TAB`**, **`TAB3`**: Formatting helpers + +#### Icon Variables +- **`CM`**, **`CROSS`**, **`INFO`**, **`OS`**, **`OSVERSION`**, etc.: Message icons + +#### Configuration Variables +- **`RETRY_NUM`**, **`RETRY_EVERY`**: Retry settings +- **`STD`**: Standard mode setting +- **`SILENT_LOGFILE`**: Log file path + +#### State Variables +- **`_CORE_FUNC_LOADED`**: Loading prevention +- **`__FUNCTIONS_LOADED`**: Function loading prevention +- **`SPINNER_PID`**, **`SPINNER_MSG`**: Spinner state +- **`MSG_INFO_SHOWN`**: Message tracking + +## Integration Patterns + +### Standard Integration Pattern + +```bash +#!/usr/bin/env bash +# Standard integration pattern + +# 1. Source core.func first +source core.func + +# 2. Run system checks +pve_check +arch_check +shell_check +root_check + +# 3. Set up error handling +trap 'stop_spinner' EXIT INT TERM + +# 4. Use UI functions +msg_info "Starting operation..." + +# 5. Use silent execution +silent command + +# 6. Show completion +msg_ok "Operation completed" +``` + +### Minimal Integration Pattern + +```bash +#!/usr/bin/env bash +# Minimal integration pattern + +source core.func +pve_check +root_check + +msg_info "Running operation..." +silent command +msg_ok "Operation completed" +``` + +### Advanced Integration Pattern + +```bash +#!/usr/bin/env bash +# Advanced integration pattern + +source core.func + +# System validation +pve_check +arch_check +shell_check +root_check +ssh_check + +# Error handling +trap 'stop_spinner' EXIT INT TERM + +# Verbose mode handling +if is_verbose_mode; then + msg_info "Verbose mode enabled" +fi + +# OS-specific operations +if is_alpine; then + msg_info "Alpine Linux detected" + # Alpine-specific logic +else + msg_info "Debian-based system detected" + # Debian-specific logic +fi + +# Operation execution +msg_info "Starting operation..." +if silent command; then + msg_ok "Operation succeeded" +else + msg_error "Operation failed" + exit 1 +fi +``` + +## Error Handling Integration + +### Silent Execution Error Flow + +``` +silent() command +β”œβ”€β”€ Execute command +β”œβ”€β”€ Capture output to log +β”œβ”€β”€ Check exit code +β”œβ”€β”€ If error: +β”‚ β”œβ”€β”€ Load error_handler.func +β”‚ β”œβ”€β”€ Get error explanation +β”‚ β”œβ”€β”€ Display error details +β”‚ β”œβ”€β”€ Show log excerpt +β”‚ └── Exit with error code +└── If success: Continue +``` + +### System Check Error Flow + +``` +System Check Function +β”œβ”€β”€ Check system state +β”œβ”€β”€ If valid: Return 0 +└── If invalid: + β”œβ”€β”€ Display error message + β”œβ”€β”€ Show fix instructions + β”œβ”€β”€ Sleep for user to read + └── Exit with error code +``` + +## Performance Considerations + +### Loading Optimization +- **Single Loading**: `_CORE_FUNC_LOADED` prevents multiple loading +- **Function Loading**: `__FUNCTIONS_LOADED` prevents multiple function loading +- **Lazy Loading**: Functions loaded only when needed + +### Memory Usage +- **Minimal Footprint**: Core functions use minimal memory +- **Variable Reuse**: Global variables reused across functions +- **Cleanup**: Spinner processes cleaned up on exit + +### Execution Speed +- **Fast Checks**: System checks are optimized for speed +- **Efficient Spinners**: Spinner animation uses minimal CPU +- **Quick Messages**: Message functions optimized for performance + +## Security Considerations + +### Privilege Escalation +- **Root Check**: Ensures script runs with sufficient privileges +- **Shell Check**: Validates shell environment +- **Process Validation**: Checks parent process for sudo usage + +### Input Validation +- **Parameter Checking**: Functions validate input parameters +- **Error Handling**: Proper error handling prevents crashes +- **Safe Execution**: Silent execution with proper error handling + +### System Protection +- **Version Validation**: Ensures compatible Proxmox version +- **Architecture Check**: Prevents execution on unsupported systems +- **SSH Warning**: Warns about external SSH usage + +## Future Integration Considerations + +### Extensibility +- **Function Groups**: Easy to add new function groups +- **Message Types**: Easy to add new message types +- **System Checks**: Easy to add new system checks + +### Compatibility +- **Version Support**: Easy to add new Proxmox versions +- **OS Support**: Easy to add new operating systems +- **Architecture Support**: Easy to add new architectures + +### Performance +- **Optimization**: Functions can be optimized for better performance +- **Caching**: Results can be cached for repeated operations +- **Parallelization**: Operations can be parallelized where appropriate diff --git a/docs/misc/core.func/CORE_USAGE_EXAMPLES.md b/docs/misc/core.func/CORE_USAGE_EXAMPLES.md new file mode 100644 index 000000000..c702bd2ed --- /dev/null +++ b/docs/misc/core.func/CORE_USAGE_EXAMPLES.md @@ -0,0 +1,728 @@ +# core.func Usage Examples + +## Overview + +This document provides practical usage examples for `core.func` functions, covering common scenarios, integration patterns, and best practices. + +## Basic Script Setup + +### Standard Script Initialization + +```bash +#!/usr/bin/env bash +# Standard script setup using core.func + +# Source core functions +source core.func + +# Run system checks +pve_check +arch_check +shell_check +root_check + +# Optional: Check SSH connection +ssh_check + +# Set up error handling +trap 'stop_spinner' EXIT INT TERM + +# Your script logic here +msg_info "Starting script execution" +# ... script code ... +msg_ok "Script completed successfully" +``` + +### Minimal Script Setup + +```bash +#!/usr/bin/env bash +# Minimal setup for simple scripts + +source core.func + +# Basic checks only +pve_check +root_check + +# Simple execution +msg_info "Running operation" +# ... your code ... +msg_ok "Operation completed" +``` + +## Message Display Examples + +### Progress Indication + +```bash +#!/usr/bin/env bash +source core.func + +# Show progress with spinner +msg_info "Downloading package..." +sleep 2 +msg_ok "Download completed" + +msg_info "Installing package..." +sleep 3 +msg_ok "Installation completed" + +msg_info "Configuring service..." +sleep 1 +msg_ok "Configuration completed" +``` + +### Error Handling + +```bash +#!/usr/bin/env bash +source core.func + +# Function with error handling +install_package() { + local package="$1" + + msg_info "Installing $package..." + + if silent apt-get install -y "$package"; then + msg_ok "$package installed successfully" + return 0 + else + msg_error "Failed to install $package" + return 1 + fi +} + +# Usage +if install_package "nginx"; then + msg_ok "Nginx installation completed" +else + msg_error "Nginx installation failed" + exit 1 +fi +``` + +### Warning Messages + +```bash +#!/usr/bin/env bash +source core.func + +# Show warnings for potentially dangerous operations +msg_warn "This will modify system configuration" +read -p "Continue? [y/N]: " confirm + +if [[ "$confirm" =~ ^[yY]$ ]]; then + msg_info "Proceeding with modification..." + # ... dangerous operation ... + msg_ok "Modification completed" +else + msg_info "Operation cancelled" +fi +``` + +### Custom Messages + +```bash +#!/usr/bin/env bash +source core.func + +# Custom message with specific icon and color +msg_custom "πŸš€" "\e[32m" "Launching application" +msg_custom "⚑" "\e[33m" "High performance mode enabled" +msg_custom "πŸ”’" "\e[31m" "Security mode activated" +``` + +### Debug Messages + +```bash +#!/usr/bin/env bash +source core.func + +# Enable debug mode +export var_full_verbose=1 + +# Debug messages +msg_debug "Variable value: $some_variable" +msg_debug "Function called: $FUNCNAME" +msg_debug "Current directory: $(pwd)" +``` + +## Silent Execution Examples + +### Package Management + +```bash +#!/usr/bin/env bash +source core.func + +# Update package lists +msg_info "Updating package lists..." +silent apt-get update + +# Install packages +msg_info "Installing required packages..." +silent apt-get install -y curl wget git + +# Upgrade packages +msg_info "Upgrading packages..." +silent apt-get upgrade -y + +msg_ok "Package management completed" +``` + +### File Operations + +```bash +#!/usr/bin/env bash +source core.func + +# Create directories +msg_info "Creating directory structure..." +silent mkdir -p /opt/myapp/{config,logs,data} + +# Set permissions +msg_info "Setting permissions..." +silent chmod 755 /opt/myapp +silent chmod 644 /opt/myapp/config/* + +# Copy files +msg_info "Copying configuration files..." +silent cp config/* /opt/myapp/config/ + +msg_ok "File operations completed" +``` + +### Service Management + +```bash +#!/usr/bin/env bash +source core.func + +# Start service +msg_info "Starting service..." +silent systemctl start myservice + +# Enable service +msg_info "Enabling service..." +silent systemctl enable myservice + +# Check service status +msg_info "Checking service status..." +if silent systemctl is-active --quiet myservice; then + msg_ok "Service is running" +else + msg_error "Service failed to start" +fi +``` + +### Network Operations + +```bash +#!/usr/bin/env bash +source core.func + +# Test network connectivity +msg_info "Testing network connectivity..." +if silent ping -c 1 8.8.8.8; then + msg_ok "Network connectivity confirmed" +else + msg_error "Network connectivity failed" +fi + +# Download files +msg_info "Downloading configuration..." +silent curl -fsSL https://example.com/config -o /tmp/config + +# Extract archives +msg_info "Extracting archive..." +silent tar -xzf /tmp/archive.tar.gz -C /opt/ +``` + +## System Check Examples + +### Comprehensive System Validation + +```bash +#!/usr/bin/env bash +source core.func + +# Complete system validation +validate_system() { + msg_info "Validating system requirements..." + + # Check Proxmox version + if pve_check; then + msg_ok "Proxmox VE version is supported" + fi + + # Check architecture + if arch_check; then + msg_ok "System architecture is supported" + fi + + # Check shell + if shell_check; then + msg_ok "Shell environment is correct" + fi + + # Check privileges + if root_check; then + msg_ok "Running with sufficient privileges" + fi + + # Check SSH connection + ssh_check + + msg_ok "System validation completed" +} + +# Run validation +validate_system +``` + +### Conditional System Checks + +```bash +#!/usr/bin/env bash +source core.func + +# Check if running in container +if [[ -f /.dockerenv ]] || [[ -f /run/.containerenv ]]; then + msg_warn "Running inside container" + # Skip some checks +else + # Full system checks + pve_check + arch_check +fi + +# Always check shell and privileges +shell_check +root_check +``` + +## Header Management Examples + +### Application Header Display + +```bash +#!/usr/bin/env bash +source core.func + +# Set application information +export APP="plex" +export APP_TYPE="ct" + +# Display header +header_info + +# Continue with application setup +msg_info "Setting up Plex Media Server..." +``` + +### Custom Header Handling + +```bash +#!/usr/bin/env bash +source core.func + +# Get header content +export APP="nextcloud" +export APP_TYPE="ct" + +header_content=$(get_header) +if [[ -n "$header_content" ]]; then + echo "Header found:" + echo "$header_content" +else + msg_warn "No header found for $APP" +fi +``` + +## Swap Management Examples + +### Interactive Swap Creation + +```bash +#!/usr/bin/env bash +source core.func + +# Check and create swap +if check_or_create_swap; then + msg_ok "Swap is available" +else + msg_warn "No swap available - continuing without swap" +fi +``` + +### Automated Swap Check + +```bash +#!/usr/bin/env bash +source core.func + +# Check swap without prompting +check_swap_quiet() { + if swapon --noheadings --show | grep -q 'swap'; then + msg_ok "Swap is active" + return 0 + else + msg_warn "No active swap detected" + return 1 + fi +} + +if check_swap_quiet; then + msg_info "System has sufficient swap" +else + msg_warn "Consider adding swap for better performance" +fi +``` + +## Spinner Usage Examples + +### Long-Running Operations + +```bash +#!/usr/bin/env bash +source core.func + +# Long-running operation with spinner +long_operation() { + msg_info "Processing large dataset..." + + # Simulate long operation + for i in {1..100}; do + sleep 0.1 + # Update spinner message periodically + if (( i % 20 == 0 )); then + SPINNER_MSG="Processing... $i%" + fi + done + + msg_ok "Dataset processing completed" +} + +long_operation +``` + +### Background Operations + +```bash +#!/usr/bin/env bash +source core.func + +# Background operation with spinner +background_operation() { + msg_info "Starting background process..." + + # Start spinner + SPINNER_MSG="Processing in background..." + spinner & + SPINNER_PID=$! + + # Do background work + sleep 5 + + # Stop spinner + stop_spinner + msg_ok "Background process completed" +} + +background_operation +``` + +## Integration Examples + +### With build.func + +```bash +#!/usr/bin/env bash +# Integration with build.func + +source core.func +source build.func + +# Use core functions for system validation +pve_check +arch_check +root_check + +# Use build.func for container creation +export APP="plex" +export CTID="100" +# ... container creation ... +``` + +### With tools.func + +```bash +#!/usr/bin/env bash +# Integration with tools.func + +source core.func +source tools.func + +# Use core functions for UI +msg_info "Starting maintenance tasks..." + +# Use tools.func for maintenance +update_system +cleanup_logs +optimize_storage + +msg_ok "Maintenance completed" +``` + +### With error_handler.func + +```bash +#!/usr/bin/env bash +# Integration with error_handler.func + +source core.func +source error_handler.func + +# Use core functions for execution +msg_info "Running operation..." + +# Silent execution will use error_handler for explanations +silent apt-get install -y package + +msg_ok "Operation completed" +``` + +## Best Practices Examples + +### Error Handling Pattern + +```bash +#!/usr/bin/env bash +source core.func + +# Robust error handling +run_with_error_handling() { + local operation="$1" + local description="$2" + + msg_info "$description" + + if silent "$operation"; then + msg_ok "$description completed successfully" + return 0 + else + msg_error "$description failed" + return 1 + fi +} + +# Usage +run_with_error_handling "apt-get update" "Package list update" +run_with_error_handling "apt-get install -y nginx" "Nginx installation" +``` + +### Verbose Mode Handling + +```bash +#!/usr/bin/env bash +source core.func + +# Handle verbose mode +if is_verbose_mode; then + msg_info "Verbose mode enabled - showing detailed output" + # Show more information +else + msg_info "Normal mode - showing minimal output" + # Show less information +fi +``` + +### Alpine Linux Detection + +```bash +#!/usr/bin/env bash +source core.func + +# Handle different OS types +if is_alpine; then + msg_info "Detected Alpine Linux" + # Use Alpine-specific commands + silent apk add --no-cache package +else + msg_info "Detected Debian-based system" + # Use Debian-specific commands + silent apt-get install -y package +fi +``` + +### Conditional Execution + +```bash +#!/usr/bin/env bash +source core.func + +# Conditional execution based on system state +if [[ -f /etc/nginx/nginx.conf ]]; then + msg_warn "Nginx configuration already exists" + read -p "Overwrite? [y/N]: " overwrite + if [[ "$overwrite" =~ ^[yY]$ ]]; then + msg_info "Overwriting configuration..." + # ... overwrite logic ... + else + msg_info "Skipping configuration" + fi +else + msg_info "Creating new Nginx configuration..." + # ... create logic ... +fi +``` + +## Advanced Usage Examples + +### Custom Spinner Messages + +```bash +#!/usr/bin/env bash +source core.func + +# Custom spinner with progress +download_with_progress() { + local url="$1" + local file="$2" + + msg_info "Starting download..." + + # Start spinner + SPINNER_MSG="Downloading..." + spinner & + SPINNER_PID=$! + + # Download with progress + curl -L "$url" -o "$file" --progress-bar + + # Stop spinner + stop_spinner + msg_ok "Download completed" +} + +download_with_progress "https://example.com/file.tar.gz" "/tmp/file.tar.gz" +``` + +### Message Deduplication + +```bash +#!/usr/bin/env bash +source core.func + +# Messages are automatically deduplicated +for i in {1..5}; do + msg_info "Processing item $i" + # This message will only show once +done + +# Different messages will show separately +msg_info "Starting phase 1" +msg_info "Starting phase 2" +msg_info "Starting phase 3" +``` + +### Terminal Control + +```bash +#!/usr/bin/env bash +source core.func + +# Ensure terminal control is available +ensure_tput + +# Use terminal control +clear_line +echo "This line will be cleared" +clear_line +echo "New content" +``` + +## Troubleshooting Examples + +### Debug Mode + +```bash +#!/usr/bin/env bash +source core.func + +# Enable debug mode +export var_full_verbose=1 +export VERBOSE="yes" + +# Debug information +msg_debug "Script started" +msg_debug "Current user: $(whoami)" +msg_debug "Current directory: $(pwd)" +msg_debug "Environment variables: $(env | grep -E '^(APP|CTID|VERBOSE)')" +``` + +### Silent Execution Debugging + +```bash +#!/usr/bin/env bash +source core.func + +# Debug silent execution +debug_silent() { + local cmd="$1" + local log_file="/tmp/debug.$$.log" + + echo "Command: $cmd" > "$log_file" + echo "Timestamp: $(date)" >> "$log_file" + echo "Working directory: $(pwd)" >> "$log_file" + echo "Environment:" >> "$log_file" + env >> "$log_file" + echo "--- Command Output ---" >> "$log_file" + + if silent "$cmd"; then + msg_ok "Command succeeded" + else + msg_error "Command failed - check $log_file for details" + fi +} + +debug_silent "apt-get update" +``` + +### Error Recovery + +```bash +#!/usr/bin/env bash +source core.func + +# Error recovery pattern +retry_operation() { + local max_attempts=3 + local attempt=1 + + while [[ $attempt -le $max_attempts ]]; do + msg_info "Attempt $attempt of $max_attempts" + + if silent "$@"; then + msg_ok "Operation succeeded on attempt $attempt" + return 0 + else + msg_warn "Attempt $attempt failed" + ((attempt++)) + + if [[ $attempt -le $max_attempts ]]; then + msg_info "Retrying in 5 seconds..." + sleep 5 + fi + fi + done + + msg_error "Operation failed after $max_attempts attempts" + return 1 +} + +# Usage +retry_operation "apt-get install -y package" +``` diff --git a/docs/misc/core.func/README.md b/docs/misc/core.func/README.md new file mode 100644 index 000000000..52c62af6e --- /dev/null +++ b/docs/misc/core.func/README.md @@ -0,0 +1,181 @@ +# core.func Documentation + +## Overview + +The `core.func` file provides fundamental utility functions and system checks that form the foundation for all other scripts in the Proxmox Community Scripts project. It handles basic system operations, user interface elements, validation, and core infrastructure. + +## Purpose and Use Cases + +- **System Validation**: Checks for Proxmox VE compatibility, architecture, shell requirements +- **User Interface**: Provides colored output, icons, spinners, and formatted messages +- **Core Utilities**: Basic functions used across all scripts +- **Error Handling**: Silent execution with detailed error reporting +- **System Information**: OS detection, verbose mode handling, swap management + +## Quick Reference + +### Key Function Groups +- **System Checks**: `pve_check()`, `arch_check()`, `shell_check()`, `root_check()` +- **User Interface**: `msg_info()`, `msg_ok()`, `msg_error()`, `msg_warn()`, `spinner()` +- **Core Utilities**: `silent()`, `is_alpine()`, `is_verbose_mode()`, `get_header()` +- **System Management**: `check_or_create_swap()`, `ensure_tput()` + +### Dependencies +- **External**: `curl` for downloading headers, `tput` for terminal control +- **Internal**: `error_handler.func` for error explanations + +### Integration Points +- Used by: All other `.func` files and installation scripts +- Uses: `error_handler.func` for error explanations +- Provides: Core utilities for `build.func`, `tools.func`, `api.func` + +## Documentation Files + +### πŸ“Š [CORE_FLOWCHART.md](./CORE_FLOWCHART.md) +Visual execution flows showing how core functions interact and the system validation process. + +### πŸ“š [CORE_FUNCTIONS_REFERENCE.md](./CORE_FUNCTIONS_REFERENCE.md) +Complete alphabetical reference of all functions with parameters, dependencies, and usage details. + +### πŸ’‘ [CORE_USAGE_EXAMPLES.md](./CORE_USAGE_EXAMPLES.md) +Practical examples showing how to use core functions in scripts and common patterns. + +### πŸ”— [CORE_INTEGRATION.md](./CORE_INTEGRATION.md) +How core.func integrates with other components and provides foundational services. + +## Key Features + +### System Validation +- **Proxmox VE Version Check**: Supports PVE 8.0-8.9 and 9.0 +- **Architecture Check**: Ensures AMD64 architecture (excludes PiMox) +- **Shell Check**: Validates Bash shell usage +- **Root Check**: Ensures root privileges +- **SSH Check**: Warns about external SSH usage + +### User Interface +- **Colored Output**: ANSI color codes for styled terminal output +- **Icons**: Symbolic icons for different message types +- **Spinners**: Animated progress indicators +- **Formatted Messages**: Consistent message formatting across scripts + +### Core Utilities +- **Silent Execution**: Execute commands with detailed error reporting +- **OS Detection**: Alpine Linux detection +- **Verbose Mode**: Handle verbose output settings +- **Header Management**: Download and display application headers +- **Swap Management**: Check and create swap files + +## Common Usage Patterns + +### Basic Script Setup +```bash +# Source core functions +source core.func + +# Run system checks +pve_check +arch_check +shell_check +root_check +``` + +### Message Display +```bash +# Show progress +msg_info "Installing package..." + +# Show success +msg_ok "Package installed successfully" + +# Show error +msg_error "Installation failed" + +# Show warning +msg_warn "This operation may take some time" +``` + +### Silent Command Execution +```bash +# Execute command silently with error handling +silent apt-get update +silent apt-get install -y package-name +``` + +## Environment Variables + +### Core Variables +- `VERBOSE`: Enable verbose output mode +- `SILENT_LOGFILE`: Path to silent execution log file +- `APP`: Application name for header display +- `APP_TYPE`: Application type (ct/vm) for header paths + +### Internal Variables +- `_CORE_FUNC_LOADED`: Prevents multiple loading +- `__FUNCTIONS_LOADED`: Prevents multiple function loading +- `RETRY_NUM`: Number of retry attempts (default: 10) +- `RETRY_EVERY`: Seconds between retries (default: 3) + +## Error Handling + +### Silent Execution Errors +- Commands executed via `silent()` capture output to log file +- On failure, displays error code explanation +- Shows last 10 lines of log output +- Provides command to view full log + +### System Check Failures +- Each system check function exits with appropriate error message +- Clear indication of what's wrong and how to fix it +- Graceful exit with sleep delay for user to read message + +## Best Practices + +### Script Initialization +1. Source `core.func` first +2. Run system checks early +3. Set up error handling +4. Use appropriate message functions + +### Message Usage +1. Use `msg_info()` for progress updates +2. Use `msg_ok()` for successful completions +3. Use `msg_error()` for failures +4. Use `msg_warn()` for warnings + +### Silent Execution +1. Use `silent()` for commands that might fail +2. Check return codes after silent execution +3. Provide meaningful error messages + +## Troubleshooting + +### Common Issues +1. **Proxmox Version**: Ensure running supported PVE version +2. **Architecture**: Script only works on AMD64 systems +3. **Shell**: Must use Bash shell +4. **Permissions**: Must run as root +5. **Network**: SSH warnings for external connections + +### Debug Mode +Enable verbose output for debugging: +```bash +export VERBOSE="yes" +source core.func +``` + +### Log Files +Check silent execution logs: +```bash +cat /tmp/silent.$$.log +``` + +## Related Documentation + +- [build.func](../build.func/) - Main container creation script +- [error_handler.func](../error_handler.func/) - Error handling utilities +- [tools.func](../tools.func/) - Extended utility functions +- [api.func](../api.func/) - Proxmox API interactions + +--- + +*This documentation covers the core.func file which provides fundamental utilities for all Proxmox Community Scripts.* diff --git a/docs/misc/error_handler.func/ERROR_HANDLER_FLOWCHART.md b/docs/misc/error_handler.func/ERROR_HANDLER_FLOWCHART.md new file mode 100644 index 000000000..984596d7f --- /dev/null +++ b/docs/misc/error_handler.func/ERROR_HANDLER_FLOWCHART.md @@ -0,0 +1,347 @@ +# error_handler.func Execution Flowchart + +## Main Error Handling Flow + +``` +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ Error Handler Initialization β”‚ +β”‚ Entry point when error_handler.func is sourced by other scripts β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ CATCH_ERRORS() β”‚ +β”‚ Initialize error handling traps and strict mode β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ Trap Setup Sequence β”‚ +β”‚ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ Set Strict β”‚ β”‚ Set Error β”‚ β”‚ Set Signal β”‚ β”‚ +β”‚ β”‚ Mode β”‚ β”‚ Trap β”‚ β”‚ Traps β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β€’ -Ee β”‚ β”‚ β€’ ERR trap β”‚ β”‚ β€’ EXIT trap β”‚ β”‚ +β”‚ β”‚ β€’ -o pipefail β”‚ β”‚ β€’ error_handler β”‚ β”‚ β€’ INT trap β”‚ β”‚ +β”‚ β”‚ β€’ -u (if β”‚ β”‚ function β”‚ β”‚ β€’ TERM trap β”‚ β”‚ +β”‚ β”‚ STRICT_UNSET) β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +``` + +## Error Handler Flow + +``` +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ ERROR_HANDLER() Flow β”‚ +β”‚ Main error handler triggered by ERR trap or manual call β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ Error Detection β”‚ +β”‚ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ Error Information Collection β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ +β”‚ β”‚ β”‚ Get Exit β”‚ β”‚ Get Command β”‚ β”‚ Get Line β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ Code β”‚ β”‚ Information β”‚ β”‚ Number β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ From $? or β”‚ β”‚ β€’ From β”‚ β”‚ β€’ From β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ parameter β”‚ β”‚ BASH_COMMAND β”‚ β”‚ BASH_LINENO[0] β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ Store in β”‚ β”‚ β€’ Clean $STD β”‚ β”‚ β€’ Default to β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ exit_code β”‚ β”‚ references β”‚ β”‚ "unknown" β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ β€’ Store in β”‚ β”‚ β€’ Store in β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ command β”‚ β”‚ line_number β”‚ β”‚ β”‚ +β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ Success Check β”‚ +β”‚ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ Exit Code Validation β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ +β”‚ β”‚ β”‚ Check Exit β”‚ β”‚ Success β”‚ β”‚ Error β”‚ β”‚ +β”‚ β”‚ β”‚ Code β”‚ β”‚ Path β”‚ β”‚ Path β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ If exit_code β”‚ β”‚ β€’ Return 0 β”‚ β”‚ β€’ Continue to β”‚ β”‚ +β”‚ β”‚ β”‚ == 0 β”‚ β”‚ β€’ No error β”‚ β”‚ error handling β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ Success β”‚ β”‚ processing β”‚ β”‚ β€’ Process error β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ No error β”‚ β”‚ β”‚ β”‚ information β”‚ β”‚ +β”‚ β”‚ β”‚ handling β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ Error Processing β”‚ +β”‚ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ Error Explanation β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ +β”‚ β”‚ β”‚ Get Error β”‚ β”‚ Display Error β”‚ β”‚ Log Error β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ Explanation β”‚ β”‚ Information β”‚ β”‚ Information β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ Call β”‚ β”‚ β€’ Show error β”‚ β”‚ β€’ Write to debug β”‚ β”‚ +β”‚ β”‚ β”‚ explain_exit_ β”‚ β”‚ message β”‚ β”‚ log if enabled β”‚ β”‚ +β”‚ β”‚ β”‚ code() β”‚ β”‚ β€’ Show line β”‚ β”‚ β€’ Include β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ Get human- β”‚ β”‚ number β”‚ β”‚ timestamp β”‚ β”‚ +β”‚ β”‚ β”‚ readable β”‚ β”‚ β€’ Show command β”‚ β”‚ β€’ Include exit β”‚ β”‚ +β”‚ β”‚ β”‚ message β”‚ β”‚ β€’ Show exit β”‚ β”‚ code β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ code β”‚ β”‚ β€’ Include command β”‚ β”‚ +β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ Silent Log Integration β”‚ +β”‚ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ Silent Log Display β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ +β”‚ β”‚ β”‚ Check Silent β”‚ β”‚ Display Log β”‚ β”‚ Exit with β”‚ β”‚ +β”‚ β”‚ β”‚ Log File β”‚ β”‚ Content β”‚ β”‚ Error Code β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ Check if β”‚ β”‚ β€’ Show last 20 β”‚ β”‚ β€’ Exit with β”‚ β”‚ +β”‚ β”‚ β”‚ SILENT_ β”‚ β”‚ lines β”‚ β”‚ original exit β”‚ β”‚ +β”‚ β”‚ β”‚ LOGFILE set β”‚ β”‚ β€’ Show file β”‚ β”‚ code β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ Check if β”‚ β”‚ path β”‚ β”‚ β€’ Terminate script β”‚ β”‚ +β”‚ β”‚ β”‚ file exists β”‚ β”‚ β€’ Format β”‚ β”‚ execution β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ Check if β”‚ β”‚ output β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ file has β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ content β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +``` + +## Signal Handling Flow + +``` +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ Signal Handler Flow β”‚ +β”‚ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ Signal Detection β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ +β”‚ β”‚ β”‚ SIGINT β”‚ β”‚ SIGTERM β”‚ β”‚ EXIT β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ (Ctrl+C) β”‚ β”‚ (Termination) β”‚ β”‚ (Script End) β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ User β”‚ β”‚ β€’ System β”‚ β”‚ β€’ Normal script β”‚ β”‚ +β”‚ β”‚ β”‚ interruption β”‚ β”‚ termination β”‚ β”‚ completion β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ Graceful β”‚ β”‚ β€’ Graceful β”‚ β”‚ β€’ Error exit β”‚ β”‚ +β”‚ β”‚ β”‚ handling β”‚ β”‚ handling β”‚ β”‚ β€’ Signal exit β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ Exit code β”‚ β”‚ β€’ Exit code β”‚ β”‚ β€’ Cleanup β”‚ β”‚ +β”‚ β”‚ β”‚ 130 β”‚ β”‚ 143 β”‚ β”‚ operations β”‚ β”‚ +β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ ON_INTERRUPT() Flow β”‚ +β”‚ Handles SIGINT (Ctrl+C) signals β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ Interrupt Processing β”‚ +β”‚ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ User Interruption Handling β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ +β”‚ β”‚ β”‚ Display β”‚ β”‚ Cleanup β”‚ β”‚ Exit with β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ Message β”‚ β”‚ Operations β”‚ β”‚ Code 130 β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ Show β”‚ β”‚ β€’ Stop β”‚ β”‚ β€’ Exit with β”‚ β”‚ +β”‚ β”‚ β”‚ interruption β”‚ β”‚ processes β”‚ β”‚ SIGINT code β”‚ β”‚ +β”‚ β”‚ β”‚ message β”‚ β”‚ β€’ Clean up β”‚ β”‚ β€’ Terminate script β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ Use red β”‚ β”‚ temporary β”‚ β”‚ execution β”‚ β”‚ +β”‚ β”‚ β”‚ color β”‚ β”‚ files β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ Clear β”‚ β”‚ β€’ Remove lock β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ terminal β”‚ β”‚ files β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +``` + +## Exit Handler Flow + +``` +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ ON_EXIT() Flow β”‚ +β”‚ Handles script exit cleanup β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ Exit Cleanup β”‚ +β”‚ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ Cleanup Operations β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ +β”‚ β”‚ β”‚ Lock File β”‚ β”‚ Temporary β”‚ β”‚ Exit with β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ Cleanup β”‚ β”‚ File β”‚ β”‚ Original Code β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ Cleanup β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ Check if β”‚ β”‚ β€’ Remove β”‚ β”‚ β€’ Exit with β”‚ β”‚ +β”‚ β”‚ β”‚ lockfile β”‚ β”‚ temporary β”‚ β”‚ original exit β”‚ β”‚ +β”‚ β”‚ β”‚ variable set β”‚ β”‚ files β”‚ β”‚ code β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ Check if β”‚ β”‚ β€’ Clean up β”‚ β”‚ β€’ Preserve exit β”‚ β”‚ +β”‚ β”‚ β”‚ lockfile β”‚ β”‚ process β”‚ β”‚ status β”‚ β”‚ +β”‚ β”‚ β”‚ exists β”‚ β”‚ state β”‚ β”‚ β€’ Terminate β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ Remove β”‚ β”‚ β”‚ β”‚ execution β”‚ β”‚ +β”‚ β”‚ β”‚ lockfile β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +``` + +## Error Code Explanation Flow + +``` +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ EXPLAIN_EXIT_CODE() Flow β”‚ +β”‚ Converts numeric exit codes to human-readable explanations β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ Error Code Classification β”‚ +β”‚ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ Error Code Categories β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ +β”‚ β”‚ β”‚ Generic/ β”‚ β”‚ Package β”‚ β”‚ Node.js β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ Shell β”‚ β”‚ Manager β”‚ β”‚ Errors β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ Errors β”‚ β”‚ Errors β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β€’ 243: Out of β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ 1: General β”‚ β”‚ β€’ 100: APT β”‚ β”‚ memory β”‚ β”‚ +β”‚ β”‚ β”‚ error β”‚ β”‚ package β”‚ β”‚ β€’ 245: Invalid β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ 2: Shell β”‚ β”‚ error β”‚ β”‚ option β”‚ β”‚ +β”‚ β”‚ β”‚ builtin β”‚ β”‚ β€’ 101: APT β”‚ β”‚ β€’ 246: Parse β”‚ β”‚ +β”‚ β”‚ β”‚ misuse β”‚ β”‚ config error β”‚ β”‚ error β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ 126: Cannot β”‚ β”‚ β€’ 255: DPKG β”‚ β”‚ β€’ 247: Fatal β”‚ β”‚ +β”‚ β”‚ β”‚ execute β”‚ β”‚ fatal error β”‚ β”‚ error β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ 127: Command β”‚ β”‚ β”‚ β”‚ β€’ 248: Addon β”‚ β”‚ +β”‚ β”‚ β”‚ not found β”‚ β”‚ β”‚ β”‚ failure β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ 128: Invalid β”‚ β”‚ β”‚ β”‚ β€’ 249: Inspector β”‚ β”‚ +β”‚ β”‚ β”‚ exit β”‚ β”‚ β”‚ β”‚ error β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ 130: SIGINT β”‚ β”‚ β”‚ β”‚ β€’ 254: Unknown β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ 137: SIGKILL β”‚ β”‚ β”‚ β”‚ fatal error β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ 139: Segfault β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ 143: SIGTERM β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ +β”‚ β”‚ β”‚ Python β”‚ β”‚ Database β”‚ β”‚ Proxmox β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ Errors β”‚ β”‚ Errors β”‚ β”‚ Custom β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ Errors β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ 210: Virtual β”‚ β”‚ β€’ PostgreSQL: β”‚ β”‚ β€’ 200: Lock file β”‚ β”‚ +β”‚ β”‚ β”‚ env missing β”‚ β”‚ 231-234 β”‚ β”‚ failed β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ 211: Dep β”‚ β”‚ β€’ MySQL: 241- β”‚ β”‚ β€’ 203: Missing β”‚ β”‚ +β”‚ β”‚ β”‚ resolution β”‚ β”‚ 244 β”‚ β”‚ CTID β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ 212: Install β”‚ β”‚ β€’ MongoDB: 251- β”‚ β”‚ β€’ 204: Missing β”‚ β”‚ +β”‚ β”‚ β”‚ aborted β”‚ β”‚ 254 β”‚ β”‚ PCT_OSTYPE β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β€’ 205: Invalid β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ CTID β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β€’ 209: Container β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ creation failed β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β€’ 210: Cluster β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ not quorate β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β€’ 214: No storage β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ space β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β€’ 215: CTID not β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ listed β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β€’ 216: RootFS β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ missing β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β€’ 217: Storage β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ not supported β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β€’ 220: Template β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ path error β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β€’ 222: Template β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ download failed β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β€’ 223: Template β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ not available β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β€’ 231: LXC stack β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ upgrade failed β”‚ β”‚ +β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ Default Case β”‚ +β”‚ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ Unknown Error Handling β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ +β”‚ β”‚ β”‚ Check for β”‚ β”‚ Return β”‚ β”‚ Log Unknown β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ Unknown β”‚ β”‚ Generic β”‚ β”‚ Error β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ Code β”‚ β”‚ Message β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β€’ Log to debug β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ If no match β”‚ β”‚ β€’ "Unknown β”‚ β”‚ file if enabled β”‚ β”‚ +β”‚ β”‚ β”‚ found β”‚ β”‚ error" β”‚ β”‚ β€’ Include error β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ Use default β”‚ β”‚ β€’ Return to β”‚ β”‚ code β”‚ β”‚ +β”‚ β”‚ β”‚ case β”‚ β”‚ caller β”‚ β”‚ β€’ Include β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ timestamp β”‚ β”‚ +β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +``` + +## Debug Logging Flow + +``` +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ Debug Log Integration β”‚ +β”‚ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ Debug Log Writing β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ +β”‚ β”‚ β”‚ Check Debug β”‚ β”‚ Write Error β”‚ β”‚ Format Log β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ Log File β”‚ β”‚ Information β”‚ β”‚ Entry β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ Check if β”‚ β”‚ β€’ Timestamp β”‚ β”‚ β€’ Error separator β”‚ β”‚ +β”‚ β”‚ β”‚ DEBUG_LOGFILE β”‚ β”‚ β€’ Exit code β”‚ β”‚ β€’ Structured β”‚ β”‚ +β”‚ β”‚ β”‚ set β”‚ β”‚ β€’ Explanation β”‚ β”‚ format β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ Check if β”‚ β”‚ β€’ Line number β”‚ β”‚ β€’ Easy to parse β”‚ β”‚ +β”‚ β”‚ β”‚ file exists β”‚ β”‚ β€’ Command β”‚ β”‚ β€’ Easy to read β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ Check if β”‚ β”‚ β€’ Append to β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ file writable β”‚ β”‚ file β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +``` + +## Integration Points + +### With core.func +- **Silent Execution**: Provides error explanations for silent() function +- **Color Variables**: Uses color variables for error display +- **Log Integration**: Integrates with SILENT_LOGFILE + +### With Other Scripts +- **Error Traps**: Sets up ERR trap for automatic error handling +- **Signal Traps**: Handles SIGINT, SIGTERM, and EXIT signals +- **Cleanup**: Provides cleanup on script exit + +### External Dependencies +- **None**: Pure Bash implementation +- **Color Support**: Requires color variables from core.func +- **Log Files**: Uses standard file operations diff --git a/docs/misc/error_handler.func/ERROR_HANDLER_FUNCTIONS_REFERENCE.md b/docs/misc/error_handler.func/ERROR_HANDLER_FUNCTIONS_REFERENCE.md new file mode 100644 index 000000000..2270ffb76 --- /dev/null +++ b/docs/misc/error_handler.func/ERROR_HANDLER_FUNCTIONS_REFERENCE.md @@ -0,0 +1,424 @@ +# error_handler.func Functions Reference + +## Overview + +This document provides a comprehensive alphabetical reference of all functions in `error_handler.func`, including parameters, dependencies, usage examples, and error handling. + +## Function Categories + +### Error Explanation Functions + +#### `explain_exit_code()` +**Purpose**: Convert numeric exit codes to human-readable explanations +**Parameters**: +- `$1` - Exit code to explain +**Returns**: Human-readable error explanation string +**Side Effects**: None +**Dependencies**: None +**Environment Variables Used**: None + +**Supported Exit Codes**: +- **Generic/Shell**: 1, 2, 126, 127, 128, 130, 137, 139, 143 +- **Package Manager**: 100, 101, 255 +- **Node.js**: 243, 245, 246, 247, 248, 249, 254 +- **Python**: 210, 211, 212 +- **PostgreSQL**: 231, 232, 233, 234 +- **MySQL/MariaDB**: 241, 242, 243, 244 +- **MongoDB**: 251, 252, 253, 254 +- **Proxmox Custom**: 200, 203, 204, 205, 209, 210, 214, 215, 216, 217, 220, 222, 223, 231 + +**Usage Example**: +```bash +explanation=$(explain_exit_code 127) +echo "Error 127: $explanation" +# Output: Error 127: Command not found +``` + +**Error Code Examples**: +```bash +explain_exit_code 1 # "General error / Operation not permitted" +explain_exit_code 126 # "Command invoked cannot execute (permission problem?)" +explain_exit_code 127 # "Command not found" +explain_exit_code 130 # "Terminated by Ctrl+C (SIGINT)" +explain_exit_code 200 # "Custom: Failed to create lock file" +explain_exit_code 999 # "Unknown error" +``` + +### Error Handling Functions + +#### `error_handler()` +**Purpose**: Main error handler triggered by ERR trap or manual call +**Parameters**: +- `$1` - Exit code (optional, defaults to $?) +- `$2` - Command that failed (optional, defaults to BASH_COMMAND) +**Returns**: None (exits with error code) +**Side Effects**: +- Displays detailed error information +- Logs error to debug file if enabled +- Shows silent log content if available +- Exits with original error code +**Dependencies**: `explain_exit_code()` +**Environment Variables Used**: `DEBUG_LOGFILE`, `SILENT_LOGFILE` + +**Usage Example**: +```bash +# Automatic error handling via ERR trap +set -e +trap 'error_handler' ERR + +# Manual error handling +error_handler 127 "command_not_found" +``` + +**Error Information Displayed**: +- Error message with color coding +- Line number where error occurred +- Exit code with explanation +- Command that failed +- Silent log content (last 20 lines) +- Debug log entry (if enabled) + +### Signal Handling Functions + +#### `on_interrupt()` +**Purpose**: Handle SIGINT (Ctrl+C) signals gracefully +**Parameters**: None +**Returns**: None (exits with code 130) +**Side Effects**: +- Displays interruption message +- Exits with SIGINT code (130) +**Dependencies**: None +**Environment Variables Used**: None + +**Usage Example**: +```bash +# Set up interrupt handler +trap on_interrupt INT + +# User presses Ctrl+C +# Handler displays: "Interrupted by user (SIGINT)" +# Script exits with code 130 +``` + +#### `on_terminate()` +**Purpose**: Handle SIGTERM signals gracefully +**Parameters**: None +**Returns**: None (exits with code 143) +**Side Effects**: +- Displays termination message +- Exits with SIGTERM code (143) +**Dependencies**: None +**Environment Variables Used**: None + +**Usage Example**: +```bash +# Set up termination handler +trap on_terminate TERM + +# System sends SIGTERM +# Handler displays: "Terminated by signal (SIGTERM)" +# Script exits with code 143 +``` + +### Cleanup Functions + +#### `on_exit()` +**Purpose**: Handle script exit cleanup +**Parameters**: None +**Returns**: None (exits with original exit code) +**Side Effects**: +- Removes lock file if set +- Exits with original exit code +**Dependencies**: None +**Environment Variables Used**: `lockfile` + +**Usage Example**: +```bash +# Set up exit handler +trap on_exit EXIT + +# Set lock file +lockfile="/tmp/my_script.lock" + +# Script exits normally or with error +# Handler removes lock file and exits +``` + +### Initialization Functions + +#### `catch_errors()` +**Purpose**: Initialize error handling traps and strict mode +**Parameters**: None +**Returns**: None +**Side Effects**: +- Sets strict error handling mode +- Sets up error traps +- Sets up signal traps +- Sets up exit trap +**Dependencies**: None +**Environment Variables Used**: `STRICT_UNSET` + +**Strict Mode Settings**: +- `-E`: Exit on command failure +- `-e`: Exit on any error +- `-o pipefail`: Exit on pipe failure +- `-u`: Exit on unset variables (if STRICT_UNSET=1) + +**Trap Setup**: +- `ERR`: Calls `error_handler` on command failure +- `EXIT`: Calls `on_exit` on script exit +- `INT`: Calls `on_interrupt` on SIGINT +- `TERM`: Calls `on_terminate` on SIGTERM + +**Usage Example**: +```bash +# Initialize error handling +catch_errors + +# Script now has full error handling +# All errors will be caught and handled +``` + +## Function Call Hierarchy + +### Error Handling Flow +``` +Command Failure +β”œβ”€β”€ ERR trap triggered +β”œβ”€β”€ error_handler() called +β”‚ β”œβ”€β”€ Get exit code +β”‚ β”œβ”€β”€ Get command info +β”‚ β”œβ”€β”€ Get line number +β”‚ β”œβ”€β”€ explain_exit_code() +β”‚ β”œβ”€β”€ Display error info +β”‚ β”œβ”€β”€ Log to debug file +β”‚ β”œβ”€β”€ Show silent log +β”‚ └── Exit with error code +``` + +### Signal Handling Flow +``` +Signal Received +β”œβ”€β”€ Signal trap triggered +β”œβ”€β”€ Appropriate handler called +β”‚ β”œβ”€β”€ on_interrupt() for SIGINT +β”‚ β”œβ”€β”€ on_terminate() for SIGTERM +β”‚ └── on_exit() for EXIT +└── Exit with signal code +``` + +### Initialization Flow +``` +catch_errors() +β”œβ”€β”€ Set strict mode +β”‚ β”œβ”€β”€ -E (exit on failure) +β”‚ β”œβ”€β”€ -e (exit on error) +β”‚ β”œβ”€β”€ -o pipefail (pipe failure) +β”‚ └── -u (unset variables, if enabled) +└── Set up traps + β”œβ”€β”€ ERR β†’ error_handler + β”œβ”€β”€ EXIT β†’ on_exit + β”œβ”€β”€ INT β†’ on_interrupt + └── TERM β†’ on_terminate +``` + +## Error Code Reference + +### Generic/Shell Errors +| Code | Description | +|------|-------------| +| 1 | General error / Operation not permitted | +| 2 | Misuse of shell builtins (e.g. syntax error) | +| 126 | Command invoked cannot execute (permission problem?) | +| 127 | Command not found | +| 128 | Invalid argument to exit | +| 130 | Terminated by Ctrl+C (SIGINT) | +| 137 | Killed (SIGKILL / Out of memory?) | +| 139 | Segmentation fault (core dumped) | +| 143 | Terminated (SIGTERM) | + +### Package Manager Errors +| Code | Description | +|------|-------------| +| 100 | APT: Package manager error (broken packages / dependency problems) | +| 101 | APT: Configuration error (bad sources.list, malformed config) | +| 255 | DPKG: Fatal internal error | + +### Node.js Errors +| 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 | Node.js: Inspector error | +| 254 | npm/pnpm/yarn: Unknown fatal error | + +### Python Errors +| Code | Description | +|------|-------------| +| 210 | Python: Virtualenv / uv environment missing or broken | +| 211 | Python: Dependency resolution failed | +| 212 | Python: Installation aborted (permissions or EXTERNALLY-MANAGED) | + +### Database Errors +| Code | Description | +|------|-------------| +| 231 | PostgreSQL: Connection failed (server not running / wrong socket) | +| 232 | PostgreSQL: Authentication failed (bad user/password) | +| 233 | PostgreSQL: Database does not exist | +| 234 | PostgreSQL: Fatal error in query / syntax | +| 241 | MySQL/MariaDB: Connection failed (server not running / wrong socket) | +| 242 | MySQL/MariaDB: Authentication failed (bad user/password) | +| 243 | MySQL/MariaDB: Database does not exist | +| 244 | MySQL/MariaDB: Fatal error in query / syntax | +| 251 | MongoDB: Connection failed (server not running) | +| 252 | MongoDB: Authentication failed (bad user/password) | +| 253 | MongoDB: Database not found | +| 254 | MongoDB: Fatal query error | + +### Proxmox Custom Errors +| Code | Description | +|------|-------------| +| 200 | Custom: Failed to create lock file | +| 203 | Custom: Missing CTID variable | +| 204 | Custom: Missing PCT_OSTYPE variable | +| 205 | Custom: Invalid CTID (<100) | +| 209 | Custom: Container creation failed | +| 210 | Custom: Cluster not quorate | +| 214 | Custom: Not enough storage space | +| 215 | Custom: Container ID not listed | +| 216 | Custom: RootFS entry missing in config | +| 217 | Custom: Storage does not support rootdir | +| 220 | Custom: Unable to resolve template path | +| 222 | Custom: Template download failed after 3 attempts | +| 223 | Custom: Template not available after download | +| 231 | Custom: LXC stack upgrade/retry failed | + +## Environment Variable Dependencies + +### Required Variables +- **`lockfile`**: Lock file path for cleanup (set by calling script) + +### Optional Variables +- **`DEBUG_LOGFILE`**: Path to debug log file for error logging +- **`SILENT_LOGFILE`**: Path to silent execution log file +- **`STRICT_UNSET`**: Enable strict unset variable checking (0/1) + +### Internal Variables +- **`exit_code`**: Current exit code +- **`command`**: Failed command +- **`line_number`**: Line number where error occurred +- **`explanation`**: Error explanation text + +## Error Handling Patterns + +### Automatic Error Handling +```bash +#!/usr/bin/env bash +source error_handler.func + +# Initialize error handling +catch_errors + +# All commands are now monitored +# Errors will be automatically caught and handled +``` + +### Manual Error Handling +```bash +#!/usr/bin/env bash +source error_handler.func + +# Manual error handling +if ! command -v required_tool >/dev/null 2>&1; then + error_handler 127 "required_tool not found" +fi +``` + +### Custom Error Codes +```bash +#!/usr/bin/env bash +source error_handler.func + +# Use custom error codes +if [[ ! -f /required/file ]]; then + echo "Error: Required file missing" + exit 200 # Custom error code +fi +``` + +### Signal Handling +```bash +#!/usr/bin/env bash +source error_handler.func + +# Set up signal handling +trap on_interrupt INT +trap on_terminate TERM +trap on_exit EXIT + +# Script handles signals gracefully +``` + +## Integration Examples + +### With core.func +```bash +#!/usr/bin/env bash +source core.func +source error_handler.func + +# Silent execution uses error_handler for explanations +silent apt-get install -y package +# If command fails, error_handler provides explanation +``` + +### With build.func +```bash +#!/usr/bin/env bash +source core.func +source error_handler.func +source build.func + +# Container creation with error handling +# Errors are caught and explained +``` + +### With tools.func +```bash +#!/usr/bin/env bash +source core.func +source error_handler.func +source tools.func + +# Tool operations with error handling +# All errors are properly handled and explained +``` + +## Best Practices + +### Error Handling Setup +1. Source error_handler.func early in script +2. Call catch_errors() to initialize traps +3. Use appropriate exit codes for different error types +4. Provide meaningful error messages + +### Signal Handling +1. Always set up signal traps +2. Provide graceful cleanup on interruption +3. Use appropriate exit codes for signals +4. Clean up temporary files and processes + +### Error Reporting +1. Use explain_exit_code() for user-friendly messages +2. Log errors to debug files when needed +3. Provide context information (line numbers, commands) +4. Integrate with silent execution logging + +### Custom Error Codes +1. Use Proxmox custom error codes (200-231) for container/VM errors +2. Use standard error codes for common operations +3. Document custom error codes in script comments +4. Provide clear error messages for custom codes diff --git a/docs/misc/error_handler.func/ERROR_HANDLER_INTEGRATION.md b/docs/misc/error_handler.func/ERROR_HANDLER_INTEGRATION.md new file mode 100644 index 000000000..c3cf3b5c9 --- /dev/null +++ b/docs/misc/error_handler.func/ERROR_HANDLER_INTEGRATION.md @@ -0,0 +1,512 @@ +# error_handler.func Integration Guide + +## Overview + +This document describes how `error_handler.func` integrates with other components in the Proxmox Community Scripts project, including dependencies, data flow, and API surface. + +## Dependencies + +### External Dependencies + +#### Required Commands +- **None**: Pure Bash implementation + +#### Optional Commands +- **None**: No external command dependencies + +### Internal Dependencies + +#### core.func +- **Purpose**: Provides color variables for error display +- **Usage**: Uses `RD`, `CL`, `YWB` color variables +- **Integration**: Called automatically when core.func is sourced +- **Data Flow**: Color variables β†’ error display formatting + +## Integration Points + +### With core.func + +#### Silent Execution Integration +```bash +# core.func silent() function uses error_handler.func +silent() { + local cmd="$*" + local caller_line="${BASH_LINENO[0]:-unknown}" + + # Execute command + "$@" >>"$SILENT_LOGFILE" 2>&1 + local rc=$? + + if [[ $rc -ne 0 ]]; then + # Load error_handler.func if needed + if ! declare -f explain_exit_code >/dev/null 2>&1; then + source error_handler.func + fi + + # Get error explanation + local explanation + explanation="$(explain_exit_code "$rc")" + + # Display error with explanation + printf "\e[?25h" + echo -e "\n${RD}[ERROR]${CL} in line ${RD}${caller_line}${CL}: exit code ${RD}${rc}${CL} (${explanation})" + echo -e "${RD}Command:${CL} ${YWB}${cmd}${CL}\n" + + exit "$rc" + fi +} +``` + +#### Color Variable Usage +```bash +# error_handler.func uses color variables from core.func +error_handler() { + # ... error handling logic ... + + # Use color variables for error display + echo -e "\n${RD}[ERROR]${CL} in line ${RD}${line_number}${CL}: exit code ${RD}${exit_code}${CL} (${explanation}): while executing command ${YWB}${command}${CL}\n" +} + +on_interrupt() { + echo -e "\n${RD}Interrupted by user (SIGINT)${CL}" + exit 130 +} + +on_terminate() { + echo -e "\n${RD}Terminated by signal (SIGTERM)${CL}" + exit 143 +} +``` + +### With build.func + +#### Container Creation Error Handling +```bash +# build.func uses error_handler.func for container operations +source core.func +source error_handler.func + +# Container creation with error handling +create_container() { + # Set up error handling + catch_errors + + # Container creation operations + silent pct create "$CTID" "$TEMPLATE" \ + --hostname "$HOSTNAME" \ + --memory "$MEMORY" \ + --cores "$CORES" + + # If creation fails, error_handler provides explanation +} +``` + +#### Template Download Error Handling +```bash +# build.func uses error_handler.func for template operations +download_template() { + # Template download with error handling + if ! silent curl -fsSL "$TEMPLATE_URL" -o "$TEMPLATE_FILE"; then + # error_handler provides detailed explanation + exit 222 # Template download failed + fi +} +``` + +### With tools.func + +#### Maintenance Operations Error Handling +```bash +# tools.func uses error_handler.func for maintenance operations +source core.func +source error_handler.func + +# Maintenance operations with error handling +update_system() { + catch_errors + + # System update operations + silent apt-get update + silent apt-get upgrade -y + + # Error handling provides explanations for failures +} + +cleanup_logs() { + catch_errors + + # Log cleanup operations + silent find /var/log -name "*.log" -mtime +30 -delete + + # Error handling provides explanations for permission issues +} +``` + +### With api.func + +#### API Operations Error Handling +```bash +# api.func uses error_handler.func for API operations +source core.func +source error_handler.func + +# API operations with error handling +api_call() { + catch_errors + + # API call with error handling + if ! silent curl -k -H "Authorization: PVEAPIToken=$API_TOKEN" \ + "$API_URL/api2/json/nodes/$NODE/lxc"; then + # error_handler provides explanation for API failures + exit 1 + fi +} +``` + +### With install.func + +#### Installation Process Error Handling +```bash +# install.func uses error_handler.func for installation operations +source core.func +source error_handler.func + +# Installation with error handling +install_package() { + local package="$1" + + catch_errors + + # Package installation + silent apt-get install -y "$package" + + # Error handling provides explanations for installation failures +} +``` + +### With alpine-install.func + +#### Alpine Installation Error Handling +```bash +# alpine-install.func uses error_handler.func for Alpine operations +source core.func +source error_handler.func + +# Alpine installation with error handling +install_alpine_package() { + local package="$1" + + catch_errors + + # Alpine package installation + silent apk add --no-cache "$package" + + # Error handling provides explanations for Alpine-specific failures +} +``` + +### With alpine-tools.func + +#### Alpine Tools Error Handling +```bash +# alpine-tools.func uses error_handler.func for Alpine tools +source core.func +source error_handler.func + +# Alpine tools with error handling +alpine_tool_operation() { + catch_errors + + # Alpine-specific tool operations + silent alpine_command + + # Error handling provides explanations for Alpine tool failures +} +``` + +### With passthrough.func + +#### Hardware Passthrough Error Handling +```bash +# passthrough.func uses error_handler.func for hardware operations +source core.func +source error_handler.func + +# Hardware passthrough with error handling +configure_gpu_passthrough() { + catch_errors + + # GPU passthrough operations + silent lspci | grep -i nvidia + + # Error handling provides explanations for hardware failures +} +``` + +### With vm-core.func + +#### VM Operations Error Handling +```bash +# vm-core.func uses error_handler.func for VM operations +source core.func +source error_handler.func + +# VM operations with error handling +create_vm() { + catch_errors + + # VM creation operations + silent qm create "$VMID" \ + --name "$VMNAME" \ + --memory "$MEMORY" \ + --cores "$CORES" + + # Error handling provides explanations for VM creation failures +} +``` + +## Data Flow + +### Input Data + +#### Environment Variables +- **`DEBUG_LOGFILE`**: Path to debug log file for error logging +- **`SILENT_LOGFILE`**: Path to silent execution log file +- **`STRICT_UNSET`**: Enable strict unset variable checking (0/1) +- **`lockfile`**: Lock file path for cleanup (set by calling script) + +#### Function Parameters +- **Exit codes**: Passed to `explain_exit_code()` and `error_handler()` +- **Command information**: Passed to `error_handler()` for context +- **Signal information**: Passed to signal handlers + +#### System Information +- **Exit codes**: Retrieved from `$?` variable +- **Command information**: Retrieved from `BASH_COMMAND` variable +- **Line numbers**: Retrieved from `BASH_LINENO[0]` variable +- **Process information**: Retrieved from system calls + +### Processing Data + +#### Error Code Processing +- **Code classification**: Categorize exit codes by type +- **Explanation lookup**: Map codes to human-readable messages +- **Context collection**: Gather command and line information +- **Log preparation**: Format error information for logging + +#### Signal Processing +- **Signal detection**: Identify received signals +- **Handler selection**: Choose appropriate signal handler +- **Cleanup operations**: Perform necessary cleanup +- **Exit code setting**: Set appropriate exit codes + +#### Log Processing +- **Debug logging**: Write error information to debug log +- **Silent log integration**: Display silent log content +- **Log formatting**: Format log entries for readability +- **Log analysis**: Provide log analysis capabilities + +### Output Data + +#### Error Information +- **Error messages**: Human-readable error explanations +- **Context information**: Line numbers, commands, timestamps +- **Color formatting**: ANSI color codes for terminal display +- **Log content**: Silent log excerpts and debug information + +#### System State +- **Exit codes**: Returned from functions +- **Log files**: Created and updated for error tracking +- **Cleanup status**: Lock file removal and process cleanup +- **Signal handling**: Graceful signal processing + +## API Surface + +### Public Functions + +#### Error Explanation +- **`explain_exit_code()`**: Convert exit codes to explanations +- **Parameters**: Exit code to explain +- **Returns**: Human-readable explanation string +- **Usage**: Called by error_handler() and other functions + +#### Error Handling +- **`error_handler()`**: Main error handler function +- **Parameters**: Exit code (optional), command (optional) +- **Returns**: None (exits with error code) +- **Usage**: Called by ERR trap or manually + +#### Signal Handling +- **`on_interrupt()`**: Handle SIGINT signals +- **`on_terminate()`**: Handle SIGTERM signals +- **`on_exit()`**: Handle script exit cleanup +- **Parameters**: None +- **Returns**: None (exits with signal code) +- **Usage**: Called by signal traps + +#### Initialization +- **`catch_errors()`**: Initialize error handling +- **Parameters**: None +- **Returns**: None +- **Usage**: Called to set up error handling traps + +### Internal Functions + +#### None +- All functions in error_handler.func are public +- No internal helper functions +- Direct implementation of all functionality + +### Global Variables + +#### Configuration Variables +- **`DEBUG_LOGFILE`**: Debug log file path +- **`SILENT_LOGFILE`**: Silent log file path +- **`STRICT_UNSET`**: Strict mode setting +- **`lockfile`**: Lock file path + +#### State Variables +- **`exit_code`**: Current exit code +- **`command`**: Failed command +- **`line_number`**: Line number where error occurred +- **`explanation`**: Error explanation text + +## Integration Patterns + +### Standard Integration Pattern + +```bash +#!/usr/bin/env bash +# Standard integration pattern + +# 1. Source core.func first +source core.func + +# 2. Source error_handler.func +source error_handler.func + +# 3. Initialize error handling +catch_errors + +# 4. Use silent execution +silent command + +# 5. Errors are automatically handled +``` + +### Minimal Integration Pattern + +```bash +#!/usr/bin/env bash +# Minimal integration pattern + +source error_handler.func +catch_errors + +# Basic error handling +command +``` + +### Advanced Integration Pattern + +```bash +#!/usr/bin/env bash +# Advanced integration pattern + +source core.func +source error_handler.func + +# Set up comprehensive error handling +export DEBUG_LOGFILE="/tmp/debug.log" +export SILENT_LOGFILE="/tmp/silent.log" +lockfile="/tmp/script.lock" +touch "$lockfile" + +catch_errors +trap on_interrupt INT +trap on_terminate TERM +trap on_exit EXIT + +# Advanced error handling +silent command +``` + +## Error Handling Integration + +### Automatic Error Handling +- **ERR Trap**: Automatically catches command failures +- **Error Explanation**: Provides human-readable error messages +- **Context Information**: Shows line numbers and commands +- **Log Integration**: Displays silent log content + +### Manual Error Handling +- **Custom Error Codes**: Use Proxmox custom error codes +- **Error Recovery**: Implement retry logic with error handling +- **Conditional Handling**: Different handling for different error types +- **Error Analysis**: Analyze error patterns and trends + +### Signal Handling Integration +- **Graceful Interruption**: Handle Ctrl+C gracefully +- **Clean Termination**: Handle SIGTERM signals +- **Exit Cleanup**: Clean up resources on script exit +- **Lock File Management**: Remove lock files on exit + +## Performance Considerations + +### Error Handling Overhead +- **Minimal Impact**: Error handling adds minimal overhead +- **Trap Setup**: Trap setup is done once during initialization +- **Error Processing**: Error processing is only done on failures +- **Log Writing**: Log writing is only done when enabled + +### Memory Usage +- **Minimal Footprint**: Error handler uses minimal memory +- **Variable Reuse**: Global variables reused across functions +- **No Memory Leaks**: Proper cleanup prevents memory leaks +- **Efficient Processing**: Efficient error code processing + +### Execution Speed +- **Fast Error Detection**: Quick error detection and handling +- **Efficient Explanation**: Fast error code explanation lookup +- **Minimal Delay**: Minimal delay in error handling +- **Quick Exit**: Fast exit on error conditions + +## Security Considerations + +### Error Information Disclosure +- **Controlled Disclosure**: Only necessary error information is shown +- **Log Security**: Log files have appropriate permissions +- **Sensitive Data**: Sensitive data is not logged +- **Error Sanitization**: Error messages are sanitized + +### Signal Handling Security +- **Signal Validation**: Only expected signals are handled +- **Cleanup Security**: Secure cleanup of temporary files +- **Lock File Security**: Secure lock file management +- **Process Security**: Secure process termination + +### Log File Security +- **File Permissions**: Log files have appropriate permissions +- **Log Rotation**: Log files are rotated to prevent disk filling +- **Log Cleanup**: Old log files are cleaned up +- **Log Access**: Log access is controlled + +## Future Integration Considerations + +### Extensibility +- **New Error Codes**: Easy to add new error code explanations +- **Custom Handlers**: Easy to add custom error handlers +- **Signal Extensions**: Easy to add new signal handlers +- **Log Formats**: Easy to add new log formats + +### Compatibility +- **Bash Version**: Compatible with different Bash versions +- **System Compatibility**: Compatible with different systems +- **Script Compatibility**: Compatible with different script types +- **Error Code Compatibility**: Compatible with different error codes + +### Performance +- **Optimization**: Error handling can be optimized for better performance +- **Caching**: Error explanations can be cached for faster lookup +- **Parallel Processing**: Error handling can be parallelized +- **Resource Management**: Better resource management for error handling diff --git a/docs/misc/error_handler.func/ERROR_HANDLER_USAGE_EXAMPLES.md b/docs/misc/error_handler.func/ERROR_HANDLER_USAGE_EXAMPLES.md new file mode 100644 index 000000000..cfb668711 --- /dev/null +++ b/docs/misc/error_handler.func/ERROR_HANDLER_USAGE_EXAMPLES.md @@ -0,0 +1,625 @@ +# error_handler.func Usage Examples + +## Overview + +This document provides practical usage examples for `error_handler.func` functions, covering common scenarios, integration patterns, and best practices. + +## Basic Error Handling Setup + +### Standard Script Initialization + +```bash +#!/usr/bin/env bash +# Standard error handling setup + +# Source error handler +source error_handler.func + +# Initialize error handling +catch_errors + +# Your script code here +# All errors will be automatically caught and handled +echo "Script running..." +apt-get update +apt-get install -y package +echo "Script completed successfully" +``` + +### Minimal Error Handling + +```bash +#!/usr/bin/env bash +# Minimal error handling setup + +source error_handler.func +catch_errors + +# Simple script with error handling +echo "Starting operation..." +command_that_might_fail +echo "Operation completed" +``` + +## Error Code Explanation Examples + +### Basic Error Explanation + +```bash +#!/usr/bin/env bash +source error_handler.func + +# Explain common error codes +echo "Error 1: $(explain_exit_code 1)" +echo "Error 127: $(explain_exit_code 127)" +echo "Error 130: $(explain_exit_code 130)" +echo "Error 200: $(explain_exit_code 200)" +``` + +### Error Code Testing + +```bash +#!/usr/bin/env bash +source error_handler.func + +# Test all error codes +test_error_codes() { + local codes=(1 2 126 127 128 130 137 139 143 100 101 255 200 203 204 205) + + for code in "${codes[@]}"; do + echo "Code $code: $(explain_exit_code $code)" + done +} + +test_error_codes +``` + +### Custom Error Code Usage + +```bash +#!/usr/bin/env bash +source error_handler.func + +# Use custom error codes +check_requirements() { + if [[ ! -f /required/file ]]; then + echo "Error: Required file missing" + exit 200 # Custom error code + fi + + if [[ -z "$CTID" ]]; then + echo "Error: CTID not set" + exit 203 # Custom error code + fi + + if [[ $CTID -lt 100 ]]; then + echo "Error: Invalid CTID" + exit 205 # Custom error code + fi +} + +check_requirements +``` + +## Signal Handling Examples + +### Interrupt Handling + +```bash +#!/usr/bin/env bash +source error_handler.func + +# Set up interrupt handler +trap on_interrupt INT + +echo "Script running... Press Ctrl+C to interrupt" +sleep 10 +echo "Script completed normally" +``` + +### Termination Handling + +```bash +#!/usr/bin/env bash +source error_handler.func + +# Set up termination handler +trap on_terminate TERM + +echo "Script running... Send SIGTERM to terminate" +sleep 10 +echo "Script completed normally" +``` + +### Complete Signal Handling + +```bash +#!/usr/bin/env bash +source error_handler.func + +# Set up all signal handlers +trap on_interrupt INT +trap on_terminate TERM +trap on_exit EXIT + +echo "Script running with full signal handling" +sleep 10 +echo "Script completed normally" +``` + +## Cleanup Examples + +### Lock File Cleanup + +```bash +#!/usr/bin/env bash +source error_handler.func + +# Set up lock file +lockfile="/tmp/my_script.lock" +touch "$lockfile" + +# Set up exit handler +trap on_exit EXIT + +echo "Script running with lock file..." +sleep 5 +echo "Script completed - lock file will be removed" +``` + +### Temporary File Cleanup + +```bash +#!/usr/bin/env bash +source error_handler.func + +# Create temporary files +temp_file1="/tmp/temp1.$$" +temp_file2="/tmp/temp2.$$" +touch "$temp_file1" "$temp_file2" + +# Set up cleanup +cleanup() { + rm -f "$temp_file1" "$temp_file2" + echo "Temporary files cleaned up" +} + +trap cleanup EXIT + +echo "Script running with temporary files..." +sleep 5 +echo "Script completed - temporary files will be cleaned up" +``` + +## Debug Logging Examples + +### Basic Debug Logging + +```bash +#!/usr/bin/env bash +source error_handler.func + +# Enable debug logging +export DEBUG_LOGFILE="/tmp/debug.log" +catch_errors + +echo "Script with debug logging" +apt-get update +apt-get install -y package +``` + +### Debug Log Analysis + +```bash +#!/usr/bin/env bash +source error_handler.func + +# Enable debug logging +export DEBUG_LOGFILE="/tmp/debug.log" +catch_errors + +# Function to analyze debug log +analyze_debug_log() { + if [[ -f "$DEBUG_LOGFILE" ]]; then + echo "Debug log analysis:" + echo "Total errors: $(grep -c "ERROR" "$DEBUG_LOGFILE")" + echo "Recent errors:" + tail -n 5 "$DEBUG_LOGFILE" + else + echo "No debug log found" + fi +} + +# Run script +echo "Running script..." +apt-get update + +# Analyze results +analyze_debug_log +``` + +## Silent Execution Integration + +### With core.func Silent Execution + +```bash +#!/usr/bin/env bash +source core.func +source error_handler.func + +# Silent execution with error handling +echo "Installing packages..." +silent apt-get update +silent apt-get install -y nginx + +echo "Configuring service..." +silent systemctl enable nginx +silent systemctl start nginx + +echo "Installation completed" +``` + +### Silent Execution Error Handling + +```bash +#!/usr/bin/env bash +source core.func +source error_handler.func + +# Function with silent execution and error handling +install_package() { + local package="$1" + + echo "Installing $package..." + if silent apt-get install -y "$package"; then + echo "$package installed successfully" + return 0 + else + echo "Failed to install $package" + return 1 + fi +} + +# Install multiple packages +packages=("nginx" "apache2" "mysql-server") +for package in "${packages[@]}"; do + if ! install_package "$package"; then + echo "Stopping installation due to error" + exit 1 + fi +done +``` + +## Advanced Error Handling Examples + +### Conditional Error Handling + +```bash +#!/usr/bin/env bash +source error_handler.func + +# Conditional error handling based on environment +setup_error_handling() { + if [[ "${STRICT_MODE:-0}" == "1" ]]; then + echo "Enabling strict mode" + export STRICT_UNSET=1 + fi + + catch_errors + echo "Error handling configured" +} + +setup_error_handling +``` + +### Error Recovery + +```bash +#!/usr/bin/env bash +source error_handler.func + +# Error recovery pattern +retry_operation() { + local max_attempts=3 + local attempt=1 + + while [[ $attempt -le $max_attempts ]]; do + echo "Attempt $attempt of $max_attempts" + + if silent "$@"; then + echo "Operation succeeded on attempt $attempt" + return 0 + else + echo "Attempt $attempt failed" + ((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 +} + +# Use retry pattern +retry_operation apt-get update +retry_operation apt-get install -y package +``` + +### Custom Error Handler + +```bash +#!/usr/bin/env bash +source error_handler.func + +# Custom error handler for specific operations +custom_error_handler() { + local exit_code=${1:-$?} + local command=${2:-${BASH_COMMAND:-unknown}} + + case "$exit_code" in + 127) + echo "Custom handling: Command not found - $command" + echo "Suggestions:" + echo "1. Check if the command is installed" + echo "2. Check if the command is in PATH" + echo "3. Check spelling" + ;; + 126) + echo "Custom handling: Permission denied - $command" + echo "Suggestions:" + echo "1. Check file permissions" + echo "2. Run with appropriate privileges" + echo "3. Check if file is executable" + ;; + *) + # Use default error handler + error_handler "$exit_code" "$command" + ;; + esac +} + +# Set up custom error handler +trap 'custom_error_handler' ERR + +# Test custom error handling +nonexistent_command +``` + +## Integration Examples + +### With build.func + +```bash +#!/usr/bin/env bash +# Integration with build.func + +source core.func +source error_handler.func +source build.func + +# Container creation with error handling +export APP="plex" +export CTID="100" + +# Errors will be caught and explained +# Silent execution will use error_handler for explanations +``` + +### With tools.func + +```bash +#!/usr/bin/env bash +# Integration with tools.func + +source core.func +source error_handler.func +source tools.func + +# Tool operations with error handling +# All errors are properly handled and explained +``` + +### With api.func + +```bash +#!/usr/bin/env bash +# Integration with api.func + +source core.func +source error_handler.func +source api.func + +# API operations with error handling +# Network errors and API errors are properly handled +``` + +## Best Practices Examples + +### Comprehensive Error Handling + +```bash +#!/usr/bin/env bash +# Comprehensive error handling example + +source error_handler.func + +# Set up comprehensive error handling +setup_comprehensive_error_handling() { + # Enable debug logging + export DEBUG_LOGFILE="/tmp/script_debug.log" + + # Set up lock file + lockfile="/tmp/script.lock" + touch "$lockfile" + + # Initialize error handling + catch_errors + + # Set up signal handlers + trap on_interrupt INT + trap on_terminate TERM + trap on_exit EXIT + + echo "Comprehensive error handling configured" +} + +setup_comprehensive_error_handling + +# Script operations +echo "Starting script operations..." +# ... script code ... +echo "Script operations completed" +``` + +### Error Handling for Different Scenarios + +```bash +#!/usr/bin/env bash +source error_handler.func + +# Different error handling for different scenarios +handle_package_errors() { + local exit_code=$1 + case "$exit_code" in + 100) + echo "Package manager error - trying to fix..." + apt-get --fix-broken install + ;; + 101) + echo "Configuration error - checking sources..." + apt-get update + ;; + *) + error_handler "$exit_code" + ;; + esac +} + +handle_network_errors() { + local exit_code=$1 + case "$exit_code" in + 127) + echo "Network command not found - checking connectivity..." + ping -c 1 8.8.8.8 + ;; + *) + error_handler "$exit_code" + ;; + esac +} + +# Use appropriate error handler +if [[ "$1" == "package" ]]; then + trap 'handle_package_errors $?' ERR +elif [[ "$1" == "network" ]]; then + trap 'handle_network_errors $?' ERR +else + catch_errors +fi +``` + +### Error Handling with Logging + +```bash +#!/usr/bin/env bash +source error_handler.func + +# Error handling with detailed logging +setup_logging_error_handling() { + # Create log directory + mkdir -p /var/log/script_errors + + # Set up debug logging + export DEBUG_LOGFILE="/var/log/script_errors/debug.log" + + # Set up silent logging + export SILENT_LOGFILE="/var/log/script_errors/silent.log" + + # Initialize error handling + catch_errors + + echo "Logging error handling configured" +} + +setup_logging_error_handling + +# Script operations with logging +echo "Starting logged operations..." +# ... script code ... +echo "Logged operations completed" +``` + +## Troubleshooting Examples + +### Debug Mode + +```bash +#!/usr/bin/env bash +source error_handler.func + +# Enable debug mode +export DEBUG_LOGFILE="/tmp/debug.log" +export STRICT_UNSET=1 + +catch_errors + +echo "Debug mode enabled" +# Script operations +``` + +### Error Analysis + +```bash +#!/usr/bin/env bash +source error_handler.func + +# Function to analyze errors +analyze_errors() { + local log_file="${1:-$DEBUG_LOGFILE}" + + if [[ -f "$log_file" ]]; then + echo "Error Analysis:" + echo "Total errors: $(grep -c "ERROR" "$log_file")" + echo "Error types:" + grep "ERROR" "$log_file" | awk '{print $NF}' | sort | uniq -c + echo "Recent errors:" + tail -n 10 "$log_file" + else + echo "No error log found" + fi +} + +# Run script with error analysis +analyze_errors +``` + +### Error Recovery Testing + +```bash +#!/usr/bin/env bash +source error_handler.func + +# Test error recovery +test_error_recovery() { + local test_cases=( + "nonexistent_command" + "apt-get install nonexistent_package" + "systemctl start nonexistent_service" + ) + + for test_case in "${test_cases[@]}"; do + echo "Testing: $test_case" + if silent $test_case; then + echo "Unexpected success" + else + echo "Expected failure handled" + fi + done +} + +test_error_recovery +``` diff --git a/docs/misc/error_handler.func/README.md b/docs/misc/error_handler.func/README.md new file mode 100644 index 000000000..3c4448184 --- /dev/null +++ b/docs/misc/error_handler.func/README.md @@ -0,0 +1,228 @@ +# error_handler.func Documentation + +## Overview + +The `error_handler.func` file provides comprehensive error handling and signal management for Proxmox Community Scripts. It offers detailed error code explanations, graceful error recovery, and proper cleanup mechanisms. + +## Purpose and Use Cases + +- **Error Code Explanation**: Provides human-readable explanations for exit codes +- **Signal Handling**: Manages SIGINT, SIGTERM, and other signals gracefully +- **Error Recovery**: Implements proper cleanup and error reporting +- **Debug Logging**: Records error information for troubleshooting +- **Silent Execution Support**: Integrates with core.func silent execution + +## Quick Reference + +### Key Function Groups +- **Error Explanation**: `explain_exit_code()` - Convert exit codes to human-readable messages +- **Error Handling**: `error_handler()` - Main error handler with detailed reporting +- **Signal Handlers**: `on_interrupt()`, `on_terminate()` - Graceful signal handling +- **Cleanup**: `on_exit()` - Cleanup on script exit +- **Trap Setup**: `catch_errors()` - Initialize error handling traps + +### Dependencies +- **External**: None (pure Bash implementation) +- **Internal**: Uses color variables from core.func + +### Integration Points +- Used by: All scripts via core.func silent execution +- Uses: Color variables from core.func +- Provides: Error explanations for core.func silent function + +## Documentation Files + +### πŸ“Š [ERROR_HANDLER_FLOWCHART.md](./ERROR_HANDLER_FLOWCHART.md) +Visual execution flows showing error handling processes and signal management. + +### πŸ“š [ERROR_HANDLER_FUNCTIONS_REFERENCE.md](./ERROR_HANDLER_FUNCTIONS_REFERENCE.md) +Complete alphabetical reference of all functions with parameters, dependencies, and usage details. + +### πŸ’‘ [ERROR_HANDLER_USAGE_EXAMPLES.md](./ERROR_HANDLER_USAGE_EXAMPLES.md) +Practical examples showing how to use error handling functions and common patterns. + +### πŸ”— [ERROR_HANDLER_INTEGRATION.md](./ERROR_HANDLER_INTEGRATION.md) +How error_handler.func integrates with other components and provides error handling services. + +## Key Features + +### Error Code Categories +- **Generic/Shell Errors**: Exit codes 1, 2, 126, 127, 128, 130, 137, 139, 143 +- **Package Manager Errors**: APT/DPKG errors (100, 101, 255) +- **Node.js Errors**: JavaScript runtime errors (243-249, 254) +- **Python Errors**: Python environment and dependency errors (210-212) +- **Database Errors**: PostgreSQL, MySQL, MongoDB errors (231-254) +- **Proxmox Custom Errors**: Container and VM specific errors (200-231) + +### Signal Handling +- **SIGINT (Ctrl+C)**: Graceful interruption handling +- **SIGTERM**: Graceful termination handling +- **EXIT**: Cleanup on script exit +- **ERR**: Error trap for command failures + +### Error Reporting +- **Detailed Messages**: Human-readable error explanations +- **Context Information**: Line numbers, commands, timestamps +- **Log Integration**: Silent log file integration +- **Debug Logging**: Optional debug log file support + +## Common Usage Patterns + +### Basic Error Handling Setup +```bash +#!/usr/bin/env bash +# Basic error handling setup + +source error_handler.func + +# Initialize error handling +catch_errors + +# Your script code here +# Errors will be automatically handled +``` + +### Manual Error Explanation +```bash +#!/usr/bin/env bash +source error_handler.func + +# Get error explanation +explanation=$(explain_exit_code 127) +echo "Error 127: $explanation" +# Output: Error 127: Command not found +``` + +### Custom Error Handling +```bash +#!/usr/bin/env bash +source error_handler.func + +# Custom error handling +if ! command -v required_tool >/dev/null 2>&1; then + echo "Error: required_tool not found" + exit 127 +fi +``` + +## Environment Variables + +### Debug Variables +- `DEBUG_LOGFILE`: Path to debug log file for error logging +- `SILENT_LOGFILE`: Path to silent execution log file +- `STRICT_UNSET`: Enable strict unset variable checking (0/1) + +### Internal Variables +- `lockfile`: Lock file path for cleanup (set by calling script) +- `exit_code`: Current exit code +- `command`: Failed command +- `line_number`: Line number where error occurred + +## Error Categories + +### Generic/Shell Errors +- **1**: General error / Operation not permitted +- **2**: Misuse of shell builtins (syntax error) +- **126**: Command invoked cannot execute (permission problem) +- **127**: Command not found +- **128**: Invalid argument to exit +- **130**: Terminated by Ctrl+C (SIGINT) +- **137**: Killed (SIGKILL / Out of memory) +- **139**: Segmentation fault (core dumped) +- **143**: Terminated (SIGTERM) + +### Package Manager Errors +- **100**: APT package manager error (broken packages) +- **101**: APT configuration error (bad sources.list) +- **255**: DPKG fatal internal error + +### Node.js Errors +- **243**: JavaScript heap out of memory +- **245**: Invalid command-line option +- **246**: Internal JavaScript parse error +- **247**: Fatal internal error +- **248**: Invalid C++ addon / N-API failure +- **249**: Inspector error +- **254**: npm/pnpm/yarn unknown fatal error + +### Python Errors +- **210**: Virtualenv/uv environment missing or broken +- **211**: Dependency resolution failed +- **212**: Installation aborted (permissions or EXTERNALLY-MANAGED) + +### Database Errors +- **PostgreSQL (231-234)**: Connection, authentication, database, query errors +- **MySQL/MariaDB (241-244)**: Connection, authentication, database, query errors +- **MongoDB (251-254)**: Connection, authentication, database, query errors + +### Proxmox Custom Errors +- **200**: Failed to create lock file +- **203**: Missing CTID variable +- **204**: Missing PCT_OSTYPE variable +- **205**: Invalid CTID (<100) +- **209**: Container creation failed +- **210**: Cluster not quorate +- **214**: Not enough storage space +- **215**: Container ID not listed +- **216**: RootFS entry missing in config +- **217**: Storage does not support rootdir +- **220**: Unable to resolve template path +- **222**: Template download failed after 3 attempts +- **223**: Template not available after download +- **231**: LXC stack upgrade/retry failed + +## Best Practices + +### Error Handling Setup +1. Source error_handler.func early in script +2. Call catch_errors() to initialize traps +3. Use proper exit codes for different error types +4. Provide meaningful error messages + +### Signal Handling +1. Always set up signal traps +2. Provide graceful cleanup on interruption +3. Use appropriate exit codes for signals +4. Clean up temporary files and processes + +### Error Reporting +1. Use explain_exit_code() for user-friendly messages +2. Log errors to debug files when needed +3. Provide context information (line numbers, commands) +4. Integrate with silent execution logging + +## Troubleshooting + +### Common Issues +1. **Missing Error Handler**: Ensure error_handler.func is sourced +2. **Trap Not Set**: Call catch_errors() to initialize traps +3. **Color Variables**: Ensure core.func is sourced for colors +4. **Lock Files**: Clean up lock files in on_exit() + +### Debug Mode +Enable debug logging for detailed error information: +```bash +export DEBUG_LOGFILE="/tmp/debug.log" +source error_handler.func +catch_errors +``` + +### Error Code Testing +Test error explanations: +```bash +source error_handler.func +for code in 1 2 126 127 128 130 137 139 143; do + echo "Code $code: $(explain_exit_code $code)" +done +``` + +## Related Documentation + +- [core.func](../core.func/) - Core utilities and silent execution +- [build.func](../build.func/) - Container creation with error handling +- [tools.func](../tools.func/) - Extended utilities with error handling +- [api.func](../api.func/) - API operations with error handling + +--- + +*This documentation covers the error_handler.func file which provides comprehensive error handling for all Proxmox Community Scripts.* diff --git a/docs/misc/install.func/INSTALL_FUNC_FLOWCHART.md b/docs/misc/install.func/INSTALL_FUNC_FLOWCHART.md new file mode 100644 index 000000000..73fcd69bd --- /dev/null +++ b/docs/misc/install.func/INSTALL_FUNC_FLOWCHART.md @@ -0,0 +1,117 @@ +# install.func Flowchart + +## Installation Workflow + +``` +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ Container Started β”‚ +β”‚ (Inside LXC by build.func) β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ Source Functions β”‚ + β”‚ $FUNCTIONS_FILE_PATH β”‚ + β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ setting_up_containerβ”‚ + β”‚ Display setup msg β”‚ + β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ network_check() β”‚ + β”‚ (Verify internet) β”‚ + β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”˜ + β”‚ β”‚ + OK FAIL + β”‚ β”‚ + β”‚ β–Ό + β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ β”‚ Retry Check β”‚ + β”‚ β”‚ 3 attempts β”‚ + β”‚ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”˜ + β”‚ β”‚ β”‚ + β”‚ OK FAIL + β”‚ β”‚ β”‚ + β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ + β”‚ β”‚ + β–Ό β–Ό + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ update_os() β”‚ β”‚ Exit Error β”‚ + β”‚ (apt update/upgrade) β”‚ β”‚ No internet β”‚ + β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ verb_ip6() [optional]β”‚ + β”‚ (Enable IPv6) β”‚ + β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ Application β”‚ + β”‚ Installation β”‚ + β”‚ (Main work) β”‚ + β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β”Œβ”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ β”‚ + SUCCESS FAILED + β”‚ β”‚ + β”‚ └─ error_handler catches + β”‚ (if catch_errors active) + β”‚ + β–Ό + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ motd_ssh() β”‚ + β”‚ (Setup SSH/MOTD) β”‚ + β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ customize() β”‚ + β”‚ (Apply settings) β”‚ + β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ cleanup_lxc() β”‚ + β”‚ (Final cleanup) β”‚ + β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ Installation β”‚ + β”‚ Complete βœ“ β”‚ + β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +``` + +## Network Check Retry Logic + +``` +network_check() + β”‚ + β”œβ”€ Ping 8.8.8.8 (Google DNS) + β”‚ └─ Response? + β”‚ β”œβ”€ YES: Continue + β”‚ └─ NO: Retry + β”‚ + β”œβ”€ Retry 1 + β”‚ └─ Wait 5s, ping again + β”‚ + β”œβ”€ Retry 2 + β”‚ └─ Wait 5s, ping again + β”‚ + └─ Retry 3 + β”œβ”€ If OK: Continue + └─ If FAIL: Exit Error + (Network unavailable) +``` + +--- + +**Visual Reference for**: install.func container setup workflows +**Last Updated**: December 2025 diff --git a/docs/misc/install.func/INSTALL_FUNC_FUNCTIONS_REFERENCE.md b/docs/misc/install.func/INSTALL_FUNC_FUNCTIONS_REFERENCE.md new file mode 100644 index 000000000..40ff0ae6f --- /dev/null +++ b/docs/misc/install.func/INSTALL_FUNC_FUNCTIONS_REFERENCE.md @@ -0,0 +1,237 @@ +# install.func Functions Reference + +Complete reference of all functions in install.func with detailed usage information. + +## Function Index + +- `setting_up_container()` - Initialize container setup +- `network_check()` - Verify network connectivity +- `update_os()` - Update OS packages +- `verb_ip6()` - Enable IPv6 +- `motd_ssh()` - Configure SSH and MOTD +- `customize()` - Apply container customizations +- `cleanup_lxc()` - Final container cleanup + +--- + +## Core Functions + +### setting_up_container() + +Display setup message and initialize container environment. + +**Signature**: +```bash +setting_up_container +``` + +**Purpose**: Announce container initialization and set initial environment + +**Usage**: +```bash +#!/usr/bin/env bash +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" + +setting_up_container +# Output: ⏳ Setting up container... +``` + +--- + +### network_check() + +Verify network connectivity with automatic retry logic. + +**Signature**: +```bash +network_check +``` + +**Purpose**: Ensure internet connectivity before critical operations + +**Behavior**: +- Pings 8.8.8.8 (Google DNS) +- 3 attempts with 5-second delays +- Exits with error if all attempts fail + +**Usage**: +```bash +network_check +# If no internet: Exits with error message +# If internet OK: Continues to next step +``` + +**Error Handling**: +```bash +if ! network_check; then + msg_error "No internet connection" + exit 1 +fi +``` + +--- + +### update_os() + +Update OS packages with error handling. + +**Signature**: +```bash +update_os +``` + +**Purpose**: Prepare container with latest packages + +**On Debian/Ubuntu**: +- Runs: `apt-get update && apt-get upgrade -y` + +**On Alpine**: +- Runs: `apk update && apk upgrade` + +**Usage**: +```bash +update_os +``` + +--- + +### verb_ip6() + +Enable IPv6 support in container (optional). + +**Signature**: +```bash +verb_ip6 +``` + +**Purpose**: Enable IPv6 if needed for application + +**Usage**: +```bash +verb_ip6 # Enable IPv6 +network_check # Verify connectivity with IPv6 +``` + +--- + +### motd_ssh() + +Configure SSH daemon and MOTD for container access. + +**Signature**: +```bash +motd_ssh +``` + +**Purpose**: Setup SSH and create login message + +**Configures**: +- SSH daemon startup and keys +- Custom MOTD displaying application access info +- SSH port and security settings + +**Usage**: +```bash +motd_ssh +# SSH is now configured and application info is in MOTD +``` + +--- + +### customize() + +Apply container customizations and final setup. + +**Signature**: +```bash +customize +``` + +**Purpose**: Apply any remaining customizations + +**Usage**: +```bash +customize +``` + +--- + +### cleanup_lxc() + +Final cleanup and completion of installation. + +**Signature**: +```bash +cleanup_lxc +``` + +**Purpose**: Remove temporary files and finalize installation + +**Cleans**: +- Temporary installation files +- Package manager cache +- Log files from installation process + +**Usage**: +```bash +cleanup_lxc +# Installation is now complete and ready +``` + +--- + +## Common Patterns + +### Basic Installation Pattern + +```bash +#!/usr/bin/env bash +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" + +setting_up_container +network_check +update_os + +# ... application installation ... + +motd_ssh +customize +cleanup_lxc +``` + +### With IPv6 Support + +```bash +#!/usr/bin/env bash +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" + +setting_up_container +verb_ip6 # Enable IPv6 +network_check +update_os + +# ... application installation ... +``` + +### With Error Handling + +```bash +#!/usr/bin/env bash +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" + +catch_errors # Setup error trapping +setting_up_container + +if ! network_check; then + msg_error "Network connectivity failed" + exit 1 +fi + +update_os +``` + +--- + +**Last Updated**: December 2025 +**Total Functions**: 7 +**Maintained by**: community-scripts team diff --git a/docs/misc/install.func/INSTALL_FUNC_INTEGRATION.md b/docs/misc/install.func/INSTALL_FUNC_INTEGRATION.md new file mode 100644 index 000000000..2715cad50 --- /dev/null +++ b/docs/misc/install.func/INSTALL_FUNC_INTEGRATION.md @@ -0,0 +1,104 @@ +# install.func Integration Guide + +How install.func integrates with the ProxmoxVE ecosystem and connects to other function libraries. + +## Component Integration + +### install.func in the Installation Pipeline + +``` +install/app-install.sh (container-side) + β”‚ + β”œβ”€ Sources: core.func (messaging) + β”œβ”€ Sources: error_handler.func (error handling) + β”‚ + β”œβ”€ β˜… Uses: install.func β˜… + β”‚ β”œβ”€ setting_up_container() + β”‚ β”œβ”€ network_check() + β”‚ β”œβ”€ update_os() + β”‚ └─ motd_ssh() + β”‚ + β”œβ”€ Uses: tools.func (package installation) + β”‚ + └─ Back to install.func: + β”œβ”€ customize() + └─ cleanup_lxc() +``` + +### Integration with tools.func + +install.func and tools.func work together: + +``` +setting_up_container() [install.func] + β”‚ +update_os() [install.func] + β”‚ +pkg_update() [tools.func] +setup_nodejs() [tools.func] +setup_mariadb() [tools.func] + β”‚ +motd_ssh() [install.func] +customize() [install.func] +cleanup_lxc() [install.func] +``` + +--- + +## Dependencies + +### External Dependencies + +- `curl`, `wget` - For downloads +- `apt-get` or `apk` - Package management +- `ping` - Network verification +- `systemctl` or `rc-service` - Service management + +### Internal Dependencies + +``` +install.func uses: +β”œβ”€ core.func (for messaging and colors) +β”œβ”€ error_handler.func (for error handling) +└─ tools.func (for package operations) +``` + +--- + +## Best Practices + +### Always Follow This Pattern + +```bash +#!/usr/bin/env bash +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" + +# 1. Setup error handling +catch_errors + +# 2. Initialize container +setting_up_container + +# 3. Verify network +network_check + +# 4. Update OS +update_os + +# 5. Installation (your code) +# ... install application ... + +# 6. Configure access +motd_ssh + +# 7. Customize +customize + +# 8. Cleanup +cleanup_lxc +``` + +--- + +**Last Updated**: December 2025 +**Maintainers**: community-scripts team diff --git a/docs/misc/install.func/INSTALL_FUNC_USAGE_EXAMPLES.md b/docs/misc/install.func/INSTALL_FUNC_USAGE_EXAMPLES.md new file mode 100644 index 000000000..634dd8ee4 --- /dev/null +++ b/docs/misc/install.func/INSTALL_FUNC_USAGE_EXAMPLES.md @@ -0,0 +1,93 @@ +# install.func Usage Examples + +Practical examples for using install.func functions in application installation scripts. + +## Basic Examples + +### Example 1: Minimal Setup + +```bash +#!/usr/bin/env bash +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" + +setting_up_container +network_check +update_os + +# ... application installation ... + +motd_ssh +customize +cleanup_lxc +``` + +### Example 2: With Error Handling + +```bash +#!/usr/bin/env bash +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" + +catch_errors +setting_up_container + +if ! network_check; then + msg_error "Network failed" + exit 1 +fi + +if ! update_os; then + msg_error "OS update failed" + exit 1 +fi + +# ... continue ... +``` + +--- + +## Production Examples + +### Example 3: Full Application Installation + +```bash +#!/usr/bin/env bash +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" + +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing application" +# ... install steps ... +msg_ok "Application installed" + +motd_ssh +customize +cleanup_lxc +``` + +### Example 4: With IPv6 Support + +```bash +#!/usr/bin/env bash +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" + +catch_errors +setting_up_container +verb_ip6 +network_check +update_os + +# ... application installation ... + +motd_ssh +customize +cleanup_lxc +``` + +--- + +**Last Updated**: December 2025 +**Examples**: Basic and production patterns +**All examples production-ready** diff --git a/docs/misc/install.func/README.md b/docs/misc/install.func/README.md new file mode 100644 index 000000000..a9d7cffc7 --- /dev/null +++ b/docs/misc/install.func/README.md @@ -0,0 +1,248 @@ +# install.func Documentation + +## Overview + +The `install.func` file provides container installation workflow orchestration and fundamental operations for applications deployed inside LXC containers. It handles network setup, OS configuration, connectivity verification, and installation mechanics. + +## Purpose and Use Cases + +- **Container Setup**: Initialize new container with proper configuration +- **Network Verification**: Verify IPv4 and IPv6 connectivity +- **OS Configuration**: Update OS, apply system settings +- **Installation Workflow**: Orchestrate application installation steps +- **Error Handling**: Comprehensive signal trapping and error recovery + +## Quick Reference + +### Key Function Groups +- **Initialization**: `setting_up_container()` - Setup message and environment +- **Network**: `network_check()`, `verb_ip6()` - Connectivity verification +- **OS Configuration**: `update_os()` - OS updates and package management +- **Installation**: `motd_ssh()`, `customize()` - Container customization +- **Cleanup**: `cleanup_lxc()` - Final container cleanup + +### Dependencies +- **External**: `curl`, `apt-get`, `ping`, `dns` utilities +- **Internal**: Uses functions from `core.func`, `error_handler.func`, `tools.func` + +### Integration Points +- Used by: All install/*.sh scripts at startup +- Uses: Environment variables from build.func and core.func +- Provides: Container initialization and management services + +## Documentation Files + +### πŸ“Š [INSTALL_FUNC_FLOWCHART.md](./INSTALL_FUNC_FLOWCHART.md) +Visual execution flows showing initialization, network checks, and installation workflows. + +### πŸ“š [INSTALL_FUNC_FUNCTIONS_REFERENCE.md](./INSTALL_FUNC_FUNCTIONS_REFERENCE.md) +Complete alphabetical reference of all functions with parameters, dependencies, and usage details. + +### πŸ’‘ [INSTALL_FUNC_USAGE_EXAMPLES.md](./INSTALL_FUNC_USAGE_EXAMPLES.md) +Practical examples showing how to use installation functions and common patterns. + +### πŸ”— [INSTALL_FUNC_INTEGRATION.md](./INSTALL_FUNC_INTEGRATION.md) +How install.func integrates with other components and provides installation services. + +## Key Features + +### Container Initialization +- **Environment Setup**: Prepare container variables and functions +- **Message System**: Display installation progress with colored output +- **Error Handlers**: Setup signal trapping for proper cleanup + +### Network & Connectivity +- **IPv4 Verification**: Ping external hosts to verify internet access +- **IPv6 Support**: Optional IPv6 enablement and verification +- **DNS Checking**: Verify DNS resolution is working +- **Retry Logic**: Automatic retries for transient failures + +### OS Configuration +- **Package Updates**: Safely update OS package lists +- **System Optimization**: Disable unnecessary services (wait-online) +- **Timezone**: Validate and set container timezone +- **SSH Setup**: Configure SSH daemon and keys + +### Container Customization +- **MOTD**: Create custom login message +- **Auto-Login**: Optional passwordless root login +- **Update Script**: Register application update function +- **Customization Hooks**: Application-specific setup + +## Function Categories + +### πŸ”Ή Core Functions +- `setting_up_container()` - Display setup message and set environment +- `network_check()` - Verify network connectivity +- `update_os()` - Update OS packages with retry logic +- `verb_ip6()` - Enable IPv6 (optional) + +### πŸ”Ή Configuration Functions +- `motd_ssh()` - Setup MOTD and SSH configuration +- `customize()` - Apply container customizations +- `cleanup_lxc()` - Final cleanup before completion + +### πŸ”Ή Utility Functions +- `create_update_script()` - Register application update function +- `set_timezone()` - Configure container timezone +- `disable_wait_online()` - Disable systemd-networkd-wait-online + +## Execution Flow + +``` +Container Started + ↓ +source $FUNCTIONS_FILE_PATH + ↓ +setting_up_container() ← Display "Setting up container..." + ↓ +network_check() ← Verify internet connectivity + ↓ +update_os() ← Update package lists + ↓ +[Application-Specific Installation] + ↓ +motd_ssh() ← Configure SSH/MOTD +customize() ← Apply customizations + ↓ +cleanup_lxc() ← Final cleanup + ↓ +Installation Complete +``` + +## Common Usage Patterns + +### Basic Container Setup +```bash +#!/usr/bin/env bash +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" +setting_up_container +network_check +update_os + +# ... application installation ... + +motd_ssh +customize +cleanup_lxc +``` + +### With Optional IPv6 +```bash +#!/usr/bin/env bash +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" +setting_up_container +verb_ip6 # Enable IPv6 +network_check +update_os + +# ... installation ... + +motd_ssh +customize +cleanup_lxc +``` + +### With Custom Update Script +```bash +#!/usr/bin/env bash +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" +setting_up_container +network_check +update_os + +# ... installation ... + +# Register update function +function update_script() { + # Update logic here +} +export -f update_script + +motd_ssh +customize +cleanup_lxc +``` + +## Best Practices + +### βœ… DO +- Call `setting_up_container()` at the start +- Check `network_check()` output before main installation +- Use `$STD` variable for silent operations +- Call `cleanup_lxc()` at the very end +- Test network connectivity before critical operations + +### ❌ DON'T +- Skip network verification +- Assume internet is available +- Hardcode container paths +- Use `echo` instead of `msg_*` functions +- Forget to call cleanup at the end + +## Environment Variables + +### Available Variables +- `$FUNCTIONS_FILE_PATH` - Path to core functions (set by build.func) +- `$CTID` - Container ID number +- `$NSAPP` - Normalized application name (lowercase) +- `$APP` - Application display name +- `$STD` - Output suppression (`silent` or empty) +- `$VERBOSE` - Verbose output mode (`yes` or `no`) + +### Setting Container Variables +```bash +CONTAINER_TIMEZONE="UTC" +CONTAINER_HOSTNAME="myapp-container" +CONTAINER_FQDN="myapp.example.com" +``` + +## Troubleshooting + +### "Network check failed" +```bash +# Container may not have internet access +# Check: +ping 8.8.8.8 # External connectivity +nslookup example.com # DNS resolution +ip route show # Routing table +``` + +### "Package update failed" +```bash +# APT may be locked by another process +ps aux | grep apt # Check for running apt +# Or wait for existing apt to finish +sleep 30 +update_os +``` + +### "Cannot source functions" +```bash +# $FUNCTIONS_FILE_PATH may not be set +# This variable is set by build.func before running install script +# If missing, the install script was not called properly +``` + +## Related Documentation + +- **[tools.func/](../tools.func/)** - Package and tool installation +- **[core.func/](../core.func/)** - Utility functions and messaging +- **[error_handler.func/](../error_handler.func/)** - Error handling +- **[alpine-install.func/](../alpine-install.func/)** - Alpine-specific setup +- **[UPDATED_APP-install.md](../../UPDATED_APP-install.md)** - Application script guide + +## Recent Updates + +### Version 2.0 (Dec 2025) +- βœ… Improved network connectivity checks +- βœ… Enhanced OS update error handling +- βœ… Added IPv6 support with verb_ip6() +- βœ… Better timezone validation +- βœ… Streamlined cleanup procedures + +--- + +**Last Updated**: December 2025 +**Maintainers**: community-scripts team +**License**: MIT diff --git a/docs/misc/tools.func/README.md b/docs/misc/tools.func/README.md new file mode 100644 index 000000000..c5e4b96de --- /dev/null +++ b/docs/misc/tools.func/README.md @@ -0,0 +1,234 @@ +# tools.func Documentation + +## Overview + +The `tools.func` file provides a comprehensive collection of helper functions for robust package management, repository management, and tool installation in Debian/Ubuntu-based systems. It is the central hub for installing services, databases, programming languages, and development tools in containers. + +## Purpose and Use Cases + +- **Package Management**: Robust APT/DPKG operations with retry logic +- **Repository Setup**: Prepare and configure package repositories safely +- **Tool Installation**: Install 30+ tools (Node.js, PHP, databases, etc.) +- **Dependency Handling**: Manage complex installation workflows +- **Error Recovery**: Automatic recovery from network failures + +## Quick Reference + +### Key Function Groups +- **Package Helpers**: `pkg_install()`, `pkg_update()`, `pkg_remove()` - APT operations with retry +- **Repository Setup**: `setup_deb822_repo()` - Modern repository configuration +- **Tool Installation**: `setup_nodejs()`, `setup_php()`, `setup_mariadb()`, etc. - 30+ tool functions +- **System Utilities**: `disable_wait_online()`, `customize()` - System optimization +- **Container Setup**: `setting_up_container()`, `motd_ssh()` - Container initialization + +### Dependencies +- **External**: `curl`, `wget`, `apt-get`, `gpg` +- **Internal**: Uses functions from `core.func`, `install.func`, `error_handler.func` + +### Integration Points +- Used by: All install scripts for dependency installation +- Uses: Environment variables from build.func and core.func +- Provides: Tool installation, package management, and repository services + +## Documentation Files + +### πŸ“Š [TOOLS_FUNC_FLOWCHART.md](./TOOLS_FUNC_FLOWCHART.md) +Visual execution flows showing package management, tool installation, and repository setup workflows. + +### πŸ“š [TOOLS_FUNC_FUNCTIONS_REFERENCE.md](./TOOLS_FUNC_FUNCTIONS_REFERENCE.md) +Complete alphabetical reference of all 30+ functions with parameters, dependencies, and usage details. + +### πŸ’‘ [TOOLS_FUNC_USAGE_EXAMPLES.md](./TOOLS_FUNC_USAGE_EXAMPLES.md) +Practical examples showing how to use tool installation functions and common patterns. + +### πŸ”— [TOOLS_FUNC_INTEGRATION.md](./TOOLS_FUNC_INTEGRATION.md) +How tools.func integrates with other components and provides package/tool services. + +### πŸ”§ [TOOLS_FUNC_ENVIRONMENT_VARIABLES.md](./TOOLS_FUNC_ENVIRONMENT_VARIABLES.md) +Complete reference of environment variables and configuration options. + +## Key Features + +### Robust Package Management +- **Automatic Retry Logic**: 3 attempts with backoff for transient failures +- **Silent Mode**: Suppress output with `$STD` variable +- **Error Recovery**: Automatic cleanup of broken packages +- **Atomic Operations**: Ensure consistent state even on failure + +### Tool Installation Coverage +- **Node.js Ecosystem**: Node.js, npm, yarn, pnpm +- **PHP Stack**: PHP-FPM, PHP-CLI, Composer +- **Databases**: MariaDB, PostgreSQL, MongoDB +- **Development Tools**: Git, build-essential, Docker +- **Monitoring**: Grafana, Prometheus, Telegraf +- **And 20+ more...** + +### Repository Management +- **Deb822 Format**: Modern standardized repository format +- **Keyring Handling**: Automatic GPG key management +- **Cleanup**: Removes legacy repositories and keyrings +- **Validation**: Verifies repository accessibility before use + +## Common Usage Patterns + +### Installing a Tool +```bash +setup_nodejs "20" # Install Node.js v20 +setup_php "8.2" # Install PHP 8.2 +setup_mariadb "11" # Install MariaDB 11 +``` + +### Safe Package Operations +```bash +pkg_update # Update package lists with retry +pkg_install curl wget # Install packages safely +pkg_remove old-tool # Remove package cleanly +``` + +### Setting Up Repositories +```bash +setup_deb822_repo "ppa:example/ppa" "example-app" "jammy" "http://example.com" "release" +``` + +## Function Categories + +### πŸ”Ή Core Package Functions +- `pkg_install()` - Install packages with retry logic +- `pkg_update()` - Update package lists safely +- `pkg_remove()` - Remove packages completely + +### πŸ”Ή Repository Functions +- `setup_deb822_repo()` - Add repository in deb822 format +- `cleanup_repo_metadata()` - Clean GPG keys and old repos +- `check_repository()` - Verify repository is accessible + +### πŸ”Ή Tool Installation Functions (30+) +**Programming Languages**: +- `setup_nodejs()` - Node.js with npm +- `setup_php()` - PHP-FPM and CLI +- `setup_python()` - Python 3 with pip +- `setup_ruby()` - Ruby with gem +- `setup_golang()` - Go programming language + +**Databases**: +- `setup_mariadb()` - MariaDB server +- `setup_postgresql()` - PostgreSQL database +- `setup_mongodb()` - MongoDB NoSQL +- `setup_redis()` - Redis cache + +**Web Servers & Proxies**: +- `setup_nginx()` - Nginx web server +- `setup_apache()` - Apache HTTP server +- `setup_caddy()` - Caddy web server +- `setup_traefik()` - Traefik reverse proxy + +**Containers & Virtualization**: +- `setup_docker()` - Docker container runtime +- `setup_podman()` - Podman container runtime + +**Development & System Tools**: +- `setup_git()` - Git version control +- `setup_docker_compose()` - Docker Compose +- `setup_composer()` - PHP dependency manager +- `setup_build_tools()` - C/C++ compilation tools + +**Monitoring & Logging**: +- `setup_grafana()` - Grafana dashboards +- `setup_prometheus()` - Prometheus monitoring +- `setup_telegraf()` - Telegraf metrics collector + +### πŸ”Ή System Configuration Functions +- `setting_up_container()` - Container initialization message +- `network_check()` - Verify network connectivity +- `update_os()` - Update OS packages safely +- `customize()` - Apply container customizations +- `motd_ssh()` - Configure SSH and MOTD +- `cleanup_lxc()` - Final container cleanup + +## Best Practices + +### βœ… DO +- Use `$STD` to suppress output in production scripts +- Chain multiple tool installations together +- Check for tool availability before using +- Use version parameters when available +- Test new repositories before production use + +### ❌ DON'T +- Mix package managers (apt and apk in same script) +- Hardcode tool versions directly +- Skip error checking on package operations +- Use `apt-get install -y` without `$STD` +- Leave temporary files after installation + +## Recent Updates + +### Version 2.0 (Dec 2025) +- βœ… Added `setup_deb822_repo()` for modern repository format +- βœ… Improved error handling with automatic cleanup +- βœ… Added 5 new tool installation functions +- βœ… Enhanced package retry logic with backoff +- βœ… Standardized tool version handling + +## Integration with Other Functions + +``` +tools.func + β”œβ”€β”€ Uses: core.func (messaging, colors) + β”œβ”€β”€ Uses: error_handler.func (exit codes, trapping) + β”œβ”€β”€ Uses: install.func (network_check, update_os) + β”‚ + └── Used by: All install/*.sh scripts + β”œβ”€β”€ For: Package installation + β”œβ”€β”€ For: Tool setup + └── For: Repository management +``` + +## Troubleshooting + +### "Package manager is locked" +```bash +# Wait for apt lock to release +sleep 10 +pkg_update +``` + +### "GPG key not found" +```bash +# Repository setup will handle this automatically +# If manual fix needed: +cleanup_repo_metadata +setup_deb822_repo ... +``` + +### "Tool installation failed" +```bash +# Enable verbose output +export var_verbose="yes" +setup_nodejs "20" +``` + +## Contributing + +When adding new tool installation functions: + +1. Follow the `setup_TOOLNAME()` naming convention +2. Accept version as first parameter +3. Check if tool already installed +4. Use `$STD` for output suppression +5. Set version file: `/opt/TOOLNAME_version.txt` +6. Document in TOOLS_FUNC_FUNCTIONS_REFERENCE.md + +## Related Documentation + +- **[build.func/](../build.func/)** - Container creation orchestrator +- **[core.func/](../core.func/)** - Utility functions and messaging +- **[install.func/](../install.func/)** - Installation workflow management +- **[error_handler.func/](../error_handler.func/)** - Error handling and recovery +- **[UPDATED_APP-install.md](../../UPDATED_APP-install.md)** - Application script guide + +--- + +**Last Updated**: December 2025 +**Maintainers**: community-scripts team +**License**: MIT diff --git a/docs/misc/tools.func/TOOLS_FUNC_FLOWCHART.md b/docs/misc/tools.func/TOOLS_FUNC_FLOWCHART.md new file mode 100644 index 000000000..b55da22c8 --- /dev/null +++ b/docs/misc/tools.func/TOOLS_FUNC_FLOWCHART.md @@ -0,0 +1,199 @@ +# tools.func Flowchart + +## Main Package Installation Flow + +``` +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ Install Script Starts β”‚ +β”‚ source tools.func β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ pkg_update()β”‚ + β”‚ (apt/apk) β”‚ + β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ Retry Logic β”‚ ◄─────┐ + β”‚ (Up to 3 tries)β”‚ β”‚ + β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ + β”‚ β”‚ + β”œβ”€ Success: Continue β”‚ + β”œβ”€ Retry 1 β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + └─ Fail: Exit + β”‚ + β–Ό + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ setup_deb822_repoβ”‚ + β”‚ (Add repository) β”‚ + β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ GPG Key Setup β”‚ + β”‚ Verify Repo OK β”‚ + β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ Tool Installationβ”‚ + β”‚ (setup_nodejs, β”‚ + β”‚ setup_php, etc.)β”‚ + β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ β”‚ + β–Ό β–Ό + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ Node.js β”‚ β”‚ MariaDB β”‚ + β”‚ setup_ β”‚ β”‚ setup_ β”‚ + β”‚ nodejs() β”‚ β”‚ mariadb() β”‚ + β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜ + β”‚ β”‚ + β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ Installation OK? β”‚ + β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”˜ + β”‚ β”‚ + YES NO + β”‚ β”‚ + β”‚ β–Ό + β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ β”‚ Rollback β”‚ + β”‚ β”‚ Error Exit β”‚ + β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ Set Version Fileβ”‚ + β”‚ /opt/TOOL_v.txt β”‚ + β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +``` + +## Repository Setup Flow (setup_deb822_repo) + +``` +setup_deb822_repo(URL, name, dist, repo_url, release) + β”‚ + β”œβ”€ Parse Parameters + β”‚ β”œβ”€ URL: Repository URL + β”‚ β”œβ”€ name: Repository name + β”‚ β”œβ”€ dist: Distro (jammy, bookworm) + β”‚ β”œβ”€ repo_url: Main URL + β”‚ └─ release: Release type + β”‚ + β”œβ”€ Add GPG Key + β”‚ β”œβ”€ Download key from URL + β”‚ β”œβ”€ Add to keyring + β”‚ └─ Trust key for deb822 + β”‚ + β”œβ”€ Create deb822 file + β”‚ β”œβ”€ /etc/apt/sources.list.d/name.sources + β”‚ β”œβ”€ Format: DEB822 + β”‚ └─ Include GPG key reference + β”‚ + β”œβ”€ Validate Repository + β”‚ β”œβ”€ apt-get update + β”‚ β”œβ”€ Check for errors + β”‚ └─ Retry if needed + β”‚ + └─ Success / Error +``` + +## Tool Installation Chain + +``` +Tools to Install: +β”œβ”€ Programming Languages +β”‚ β”œβ”€ setup_nodejs(VERSION) +β”‚ β”œβ”€ setup_php(VERSION) +β”‚ β”œβ”€ setup_python(VERSION) +β”‚ β”œβ”€ setup_ruby(VERSION) +β”‚ └─ setup_golang(VERSION) +β”‚ +β”œβ”€ Databases +β”‚ β”œβ”€ setup_mariadb(VERSION) +β”‚ β”œβ”€ setup_postgresql(VERSION) +β”‚ β”œβ”€ setup_mongodb(VERSION) +β”‚ └─ setup_redis(VERSION) +β”‚ +β”œβ”€ Web Servers +β”‚ β”œβ”€ setup_nginx() +β”‚ β”œβ”€ setup_apache() +β”‚ β”œβ”€ setup_caddy() +β”‚ └─ setup_traefik() +β”‚ +β”œβ”€ Containers +β”‚ β”œβ”€ setup_docker() +β”‚ └─ setup_podman() +β”‚ +└─ Utilities + β”œβ”€ setup_git() + β”œβ”€ setup_composer() + β”œβ”€ setup_build_tools() + └─ setup_[TOOL]() +``` + +## Package Operation Retry Logic + +``` +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ pkg_install PKG1 β”‚ +β”‚ pkg_install PKG2 β”‚ +β”‚ pkg_install PKG3 β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ APT Lock Check β”‚ + β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”˜ + β”‚ β”‚ + FREE LOCKED + β”‚ β”‚ + β”‚ β–Ό + β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ β”‚ Wait 5 sec β”‚ + β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”˜ + β”‚ β”‚ + β”‚ β–Ό + β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ β”‚ Retry Check β”‚ + β”‚ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”˜ + β”‚ β”‚ β”‚ + β”‚ OK LOCK + β”‚ β”‚ β”‚ + β”‚ β””β”€β”€β”€β”€β”˜ (loop) + β”‚ + β–Ό + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ apt-get install β”‚ + β”‚ (with $STD) β”‚ + β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”˜ + β”‚ β”‚ + SUCCESS FAILED + β”‚ β”‚ + β”‚ β–Ό + β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ β”‚ Retry Count? β”‚ + β”‚ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”˜ + β”‚ β”‚ β”‚ + β”‚ <3 β‰₯3 β”‚ + β”‚ Retry FAIL + β”‚ β”‚ + β”‚ └─────────┐ + β”‚ β”‚ + β–Ό β–Ό + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ SUCCESS β”‚ β”‚ FAILED β”‚ + β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ EXIT 1 β”‚ + β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +``` + +--- + +**Visual Reference for**: tools.func package management and tool installation +**Last Updated**: December 2025 diff --git a/docs/misc/tools.func/TOOLS_FUNC_FUNCTIONS_REFERENCE.md b/docs/misc/tools.func/TOOLS_FUNC_FUNCTIONS_REFERENCE.md new file mode 100644 index 000000000..872a1df30 --- /dev/null +++ b/docs/misc/tools.func/TOOLS_FUNC_FUNCTIONS_REFERENCE.md @@ -0,0 +1,491 @@ +# tools.func Functions Reference + +Complete alphabetical reference of all functions in tools.func with parameters, usage, and examples. + +## Function Index + +### Package Management +- `pkg_install()` - Install packages safely with retry +- `pkg_update()` - Update package lists with retry +- `pkg_remove()` - Remove packages cleanly + +### Repository Management +- `setup_deb822_repo()` - Add repository in modern deb822 format +- `cleanup_repo_metadata()` - Clean GPG keys and old repositories +- `check_repository()` - Verify repository accessibility + +### Tool Installation Functions (30+) + +**Programming Languages**: +- `setup_nodejs(VERSION)` - Install Node.js and npm +- `setup_php(VERSION)` - Install PHP-FPM and CLI +- `setup_python(VERSION)` - Install Python 3 with pip +- `setup_ruby(VERSION)` - Install Ruby with gem +- `setup_golang(VERSION)` - Install Go programming language + +**Databases**: +- `setup_mariadb(VERSION)` - Install MariaDB server +- `setup_postgresql(VERSION)` - Install PostgreSQL +- `setup_mongodb(VERSION)` - Install MongoDB +- `setup_redis(VERSION)` - Install Redis cache + +**Web Servers**: +- `setup_nginx()` - Install Nginx +- `setup_apache()` - Install Apache HTTP Server +- `setup_caddy()` - Install Caddy +- `setup_traefik()` - Install Traefik proxy + +**Containers**: +- `setup_docker()` - Install Docker +- `setup_podman()` - Install Podman + +**Development**: +- `setup_git()` - Install Git +- `setup_docker_compose()` - Install Docker Compose +- `setup_composer()` - Install PHP Composer +- `setup_build_tools()` - Install build-essential + +**Monitoring**: +- `setup_grafana()` - Install Grafana +- `setup_prometheus()` - Install Prometheus +- `setup_telegraf()` - Install Telegraf + +**System**: +- `setup_wireguard()` - Install WireGuard VPN +- `setup_netdata()` - Install Netdata monitoring +- `setup_tailscale()` - Install Tailscale +- (+ more...) + +--- + +## Core Functions + +### pkg_install() + +Install one or more packages safely with automatic retry logic and error handling. + +**Signature**: +```bash +pkg_install PACKAGE1 [PACKAGE2 ...] +``` + +**Parameters**: +- `PACKAGE1, PACKAGE2, ...` - Package names to install + +**Returns**: +- `0` - All packages installed successfully +- `1` - Installation failed after retries + +**Environment Variables**: +- `$STD` - Output suppression (`silent` or empty) + +**Example**: +```bash +pkg_install curl wget git +``` + +--- + +### pkg_update() + +Update package lists with automatic retry logic for network failures. + +**Signature**: +```bash +pkg_update +``` + +**Parameters**: None + +**Returns**: +- `0` - Package lists updated +- `1` - Failed after 3 retries + +**Example**: +```bash +pkg_update +``` + +--- + +### pkg_remove() + +Remove packages completely including dependencies. + +**Signature**: +```bash +pkg_remove PACKAGE1 [PACKAGE2 ...] +``` + +**Parameters**: +- `PACKAGE1, PACKAGE2, ...` - Package names to remove + +**Returns**: +- `0` - Packages removed +- `1` - Removal failed + +**Example**: +```bash +pkg_remove old-package outdated-tool +``` + +--- + +### setup_deb822_repo() + +Add repository in modern deb822 format (recommended over legacy format). + +**Signature**: +```bash +setup_deb822_repo REPO_URL NAME DIST MAIN_URL RELEASE +``` + +**Parameters**: +- `REPO_URL` - URL to GPG key (e.g., https://example.com/key.gpg) +- `NAME` - Repository name (e.g., "nodejs") +- `DIST` - Distribution (jammy, bookworm, etc.) +- `MAIN_URL` - Main repository URL +- `RELEASE` - Release type (main, testing, etc.) + +**Returns**: +- `0` - Repository added successfully +- `1` - Repository setup failed + +**Example**: +```bash +setup_deb822_repo \ + "https://deb.nodesource.com/gpgkey/nodesource.gpg.key" \ + "nodejs" \ + "jammy" \ + "https://deb.nodesource.com/node_20.x" \ + "main" +``` + +--- + +### cleanup_repo_metadata() + +Clean up GPG keys and old repository configurations. + +**Signature**: +```bash +cleanup_repo_metadata +``` + +**Parameters**: None + +**Returns**: +- `0` - Cleanup complete + +**Example**: +```bash +cleanup_repo_metadata +``` + +--- + +## Tool Installation Functions + +### setup_nodejs(VERSION) + +Install Node.js and npm from official repositories. + +**Signature**: +```bash +setup_nodejs VERSION +``` + +**Parameters**: +- `VERSION` - Node.js version (e.g., "20", "22", "lts") + +**Returns**: +- `0` - Installation successful +- `1` - Installation failed + +**Creates**: +- `/opt/nodejs_version.txt` - Version file + +**Example**: +```bash +setup_nodejs "20" +``` + +--- + +### setup_php(VERSION) + +Install PHP-FPM, CLI, and common extensions. + +**Signature**: +```bash +setup_php VERSION +``` + +**Parameters**: +- `VERSION` - PHP version (e.g., "8.2", "8.3") + +**Returns**: +- `0` - Installation successful +- `1` - Installation failed + +**Creates**: +- `/opt/php_version.txt` - Version file + +**Example**: +```bash +setup_php "8.3" +``` + +--- + +### setup_mariadb(VERSION) + +Install MariaDB server and client utilities. + +**Signature**: +```bash +setup_mariadb VERSION +``` + +**Parameters**: +- `VERSION` - MariaDB version (e.g., "10.6", "11.0") + +**Returns**: +- `0` - Installation successful +- `1` - Installation failed + +**Creates**: +- `/opt/mariadb_version.txt` - Version file + +**Example**: +```bash +setup_mariadb "11.0" +``` + +--- + +### setup_postgresql(VERSION) + +Install PostgreSQL server and client utilities. + +**Signature**: +```bash +setup_postgresql VERSION +``` + +**Parameters**: +- `VERSION` - PostgreSQL version (e.g., "14", "15", "16") + +**Returns**: +- `0` - Installation successful +- `1` - Installation failed + +**Creates**: +- `/opt/postgresql_version.txt` - Version file + +**Example**: +```bash +setup_postgresql "16" +``` + +--- + +### setup_docker() + +Install Docker and Docker CLI. + +**Signature**: +```bash +setup_docker +``` + +**Parameters**: None + +**Returns**: +- `0` - Installation successful +- `1` - Installation failed + +**Creates**: +- `/opt/docker_version.txt` - Version file + +**Example**: +```bash +setup_docker +``` + +--- + +### setup_composer() + +Install PHP Composer (dependency manager). + +**Signature**: +```bash +setup_composer +``` + +**Parameters**: None + +**Returns**: +- `0` - Installation successful +- `1` - Installation failed + +**Creates**: +- `/usr/local/bin/composer` - Composer executable + +**Example**: +```bash +setup_composer +``` + +--- + +### setup_build_tools() + +Install build-essential and development tools (gcc, make, etc.). + +**Signature**: +```bash +setup_build_tools +``` + +**Parameters**: None + +**Returns**: +- `0` - Installation successful +- `1` - Installation failed + +**Example**: +```bash +setup_build_tools +``` + +--- + +## System Configuration + +### setting_up_container() + +Display setup message and initialize container environment. + +**Signature**: +```bash +setting_up_container +``` + +**Example**: +```bash +setting_up_container +# Output: ⏳ Setting up container... +``` + +--- + +### motd_ssh() + +Configure SSH daemon and MOTD for container. + +**Signature**: +```bash +motd_ssh +``` + +**Example**: +```bash +motd_ssh +# Configures SSH and creates MOTD +``` + +--- + +### customize() + +Apply container customizations and final setup. + +**Signature**: +```bash +customize +``` + +**Example**: +```bash +customize +``` + +--- + +### cleanup_lxc() + +Final cleanup of temporary files and logs. + +**Signature**: +```bash +cleanup_lxc +``` + +**Example**: +```bash +cleanup_lxc +# Removes temp files, finalizes installation +``` + +--- + +## Usage Patterns + +### Basic Installation Sequence + +```bash +#!/usr/bin/env bash +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" + +pkg_update # Update package lists +setup_nodejs "20" # Install Node.js +setup_mariadb "11" # Install MariaDB + +# ... application installation ... + +motd_ssh # Setup SSH/MOTD +customize # Apply customizations +cleanup_lxc # Final cleanup +``` + +### Tool Chain Installation + +```bash +#!/usr/bin/env bash +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" + +# Install full web stack +pkg_update +setup_nginx +setup_php "8.3" +setup_mariadb "11" +setup_composer +``` + +### With Repository Setup + +```bash +#!/usr/bin/env bash +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" + +pkg_update + +# Add Node.js repository +setup_deb822_repo \ + "https://deb.nodesource.com/gpgkey/nodesource.gpg.key" \ + "nodejs" \ + "jammy" \ + "https://deb.nodesource.com/node_20.x" \ + "main" + +pkg_update +setup_nodejs "20" +``` + +--- + +**Last Updated**: December 2025 +**Total Functions**: 30+ +**Maintained by**: community-scripts team diff --git a/docs/misc/tools.func/TOOLS_FUNC_INTEGRATION.md b/docs/misc/tools.func/TOOLS_FUNC_INTEGRATION.md new file mode 100644 index 000000000..6c1f82643 --- /dev/null +++ b/docs/misc/tools.func/TOOLS_FUNC_INTEGRATION.md @@ -0,0 +1,418 @@ +# tools.func Integration Guide + +How tools.func integrates with other components and provides package/tool services to the ProxmoxVE ecosystem. + +## Component Relationships + +### tools.func in the Installation Pipeline + +``` +ct/AppName.sh (host) + β”‚ + β”œβ”€ Calls build.func + β”‚ + └─ Creates Container + β”‚ + β–Ό +install/appname-install.sh (container) + β”‚ + β”œβ”€ Sources: core.func (colors, messaging) + β”œβ”€ Sources: error_handler.func (error handling) + β”œβ”€ Sources: install.func (container setup) + β”‚ + └─ β˜… Sources: tools.func β˜… + β”‚ + β”œβ”€ pkg_update() + β”œβ”€ pkg_install() + β”œβ”€ setup_nodejs() + β”œβ”€ setup_php() + β”œβ”€ setup_mariadb() + └─ ... 30+ functions +``` + +### Integration with core.func + +**tools.func uses core.func for**: +- `msg_info()` - Display progress messages +- `msg_ok()` - Display success messages +- `msg_error()` - Display error messages +- `msg_warn()` - Display warnings +- Color codes (GN, RD, YW, BL) for formatted output +- `$STD` variable - Output suppression control + +**Example**: +```bash +# tools.func internally calls: +msg_info "Installing Node.js" # Uses core.func +setup_nodejs "20" # Setup happens +msg_ok "Node.js installed" # Uses core.func +``` + +### Integration with error_handler.func + +**tools.func uses error_handler.func for**: +- Exit code mapping to error descriptions +- Automatic error trapping (catch_errors) +- Signal handlers (SIGINT, SIGTERM, EXIT) +- Structured error reporting + +**Example**: +```bash +# If setup_nodejs fails, error_handler catches it: +catch_errors # Calls from error_handler.func +setup_nodejs "20" # If this exits non-zero + # error_handler logs and traps it +``` + +### Integration with install.func + +**tools.func coordinates with install.func for**: +- Initial OS updates (install.func) β†’ then tools (tools.func) +- Network verification before tool installation +- Package manager state validation +- Cleanup procedures after tool setup + +**Sequence**: +```bash +setting_up_container() # From install.func +network_check() # From install.func +update_os() # From install.func + +pkg_update # From tools.func +setup_nodejs() # From tools.func + +motd_ssh() # From install.func +customize() # From install.func +cleanup_lxc() # From install.func +``` + +--- + +## Integration with alpine-tools.func (Alpine Containers) + +### When to Use tools.func vs alpine-tools.func + +| Feature | tools.func (Debian) | alpine-tools.func (Alpine) | +|---------|:---:|:---:| +| Package Manager | apt-get | apk | +| Installation Scripts | install/*.sh | install/*-alpine.sh | +| Tool Setup | `setup_nodejs()` (apt) | `setup_nodejs()` (apk) | +| Repository | `setup_deb822_repo()` | `add_community_repo()` | +| Services | systemctl | rc-service | + +### Automatic Selection + +Installation scripts detect OS and source appropriate functions: + +```bash +# install/myapp-install.sh +if grep -qi 'alpine' /etc/os-release; then + # Alpine detected - uses alpine-tools.func + apk_update + apk_add package +else + # Debian detected - uses tools.func + pkg_update + pkg_install package +fi +``` + +--- + +## Dependencies Management + +### External Dependencies + +``` +tools.func requires: +β”œβ”€ curl (for HTTP requests, GPG keys) +β”œβ”€ wget (for downloads) +β”œβ”€ apt-get (package manager) +β”œβ”€ gpg (GPG key management) +β”œβ”€ openssl (for encryption) +└─ systemctl (service management on Debian) +``` + +### Internal Function Dependencies + +``` +setup_nodejs() + β”œβ”€ Calls: setup_deb822_repo() + β”œβ”€ Calls: pkg_update() + β”œβ”€ Calls: pkg_install() + └─ Uses: msg_info(), msg_ok() [from core.func] + +setup_mariadb() + β”œβ”€ Calls: setup_deb822_repo() + β”œβ”€ Calls: pkg_update() + β”œβ”€ Calls: pkg_install() + └─ Uses: msg_info(), msg_ok() + +setup_docker() + β”œβ”€ Calls: cleanup_repo_metadata() + β”œβ”€ Calls: setup_deb822_repo() + β”œβ”€ Calls: pkg_update() + └─ Uses: msg_info(), msg_ok() +``` + +--- + +## Function Call Graph + +### Complete Installation Dependency Tree + +``` +install/app-install.sh + β”‚ + β”œβ”€ setting_up_container() [install.func] + β”‚ + β”œβ”€ network_check() [install.func] + β”‚ + β”œβ”€ update_os() [install.func] + β”‚ + β”œβ”€ pkg_update() [tools.func] + β”‚ └─ Calls: apt-get update (with retry) + β”‚ + β”œβ”€ setup_nodejs("20") [tools.func] + β”‚ β”œβ”€ setup_deb822_repo() [tools.func] + β”‚ β”‚ └─ Calls: apt-get update + β”‚ β”œβ”€ pkg_update() [tools.func] + β”‚ └─ pkg_install() [tools.func] + β”‚ + β”œβ”€ setup_php("8.3") [tools.func] + β”‚ └─ Similar to setup_nodejs + β”‚ + β”œβ”€ setup_mariadb("11") [tools.func] + β”‚ └─ Similar to setup_nodejs + β”‚ + β”œβ”€ motd_ssh() [install.func] + β”‚ + β”œβ”€ customize() [install.func] + β”‚ + └─ cleanup_lxc() [install.func] +``` + +--- + +## Configuration Management + +### Environment Variables Used by tools.func + +```bash +# Output control +STD="silent" # Suppress apt/apk output +VERBOSE="yes" # Show all output + +# Package management +DEBIAN_FRONTEND="noninteractive" + +# Tool versions (optional) +NODEJS_VERSION="20" +PHP_VERSION="8.3" +POSTGRES_VERSION="16" +``` + +### Tools Configuration Files Created + +``` +/opt/ +β”œβ”€ nodejs_version.txt # Node.js version +β”œβ”€ php_version.txt # PHP version +β”œβ”€ mariadb_version.txt # MariaDB version +β”œβ”€ postgresql_version.txt # PostgreSQL version +β”œβ”€ docker_version.txt # Docker version +└─ [TOOL]_version.txt # For all installed tools + +/etc/apt/sources.list.d/ +β”œβ”€ nodejs.sources # Node.js repo (deb822) +β”œβ”€ docker.sources # Docker repo (deb822) +└─ [name].sources # Other repos (deb822) +``` + +--- + +## Error Handling Integration + +### Exit Codes from tools.func + +| Code | Meaning | Handled By | +|------|:---:|:---:| +| 0 | Success | Normal flow | +| 1 | Package installation failed | error_handler.func | +| 100-101 | APT error | error_handler.func | +| 127 | Command not found | error_handler.func | + +### Automatic Cleanup on Failure + +```bash +# If any step fails in install script: +catch_errors +pkg_update # Fail here? +setup_nodejs # Doesn't get here + +# error_handler automatically: +β”œβ”€ Logs error +β”œβ”€ Captures exit code +β”œβ”€ Calls cleanup_lxc() +└─ Exits with proper code +``` + +--- + +## Integration with build.func + +### Variable Flow + +``` +ct/app.sh + β”‚ + β”œβ”€ var_cpu="2" + β”œβ”€ var_ram="2048" + β”œβ”€ var_disk="10" + β”‚ + └─ Calls: build_container() [build.func] + β”‚ + └─ Creates container + β”‚ + └─ Calls: install/app-install.sh + β”‚ + └─ Uses: tools.func for installation +``` + +### Resource Considerations + +tools.func respects container resource limits: +- Large package installations respect allocated RAM +- Database setups use allocated disk space +- Build tools (gcc, make) stay within CPU allocation + +--- + +## Version Management + +### How tools.func Tracks Versions + +Each tool installation creates a version file: + +```bash +# setup_nodejs() creates: +echo "20.10.5" > /opt/nodejs_version.txt + +# Used by update scripts: +CURRENT=$(cat /opt/nodejs_version.txt) +LATEST=$(curl ... # fetch latest) +if [[ "$LATEST" != "$CURRENT" ]]; then + # Update needed +fi +``` + +### Integration with Update Functions + +```bash +# In ct/app.sh: +function update_script() { + # Check Node version + RELEASE=$(curl ... | jq '.version') + CURRENT=$(cat /opt/nodejs_version.txt) + + if [[ "$RELEASE" != "$CURRENT" ]]; then + # Use tools.func to upgrade + setup_nodejs "$RELEASE" + fi +} +``` + +--- + +## Best Practices for Integration + +### βœ… DO + +1. **Call functions in proper order** + ```bash + pkg_update + setup_tool "version" + ``` + +2. **Use $STD for production** + ```bash + export STD="silent" + pkg_install curl wget + ``` + +3. **Check for existing installations** + ```bash + command -v nodejs >/dev/null || setup_nodejs "20" + ``` + +4. **Coordinate with install.func** + ```bash + setting_up_container + update_os # From install.func + setup_nodejs # From tools.func + motd_ssh # Back to install.func + ``` + +### ❌ DON'T + +1. **Don't skip pkg_update** + ```bash + # Bad - may fail due to stale cache + pkg_install curl + ``` + +2. **Don't hardcode versions** + ```bash + # Bad + apt-get install nodejs=20.x + + # Good + setup_nodejs "20" + ``` + +3. **Don't mix package managers** + ```bash + # Bad + apt-get install curl + apk add wget + ``` + +4. **Don't ignore errors** + ```bash + # Bad + setup_docker || true + + # Good + if ! setup_docker; then + msg_error "Docker failed" + exit 1 + fi + ``` + +--- + +## Troubleshooting Integration Issues + +### "Package installation fails" +- Check: `pkg_update` was called first +- Check: Package name is correct for OS +- Solution: Manually verify in container + +### "Tool not accessible after installation" +- Check: Tool added to PATH +- Check: Version file created +- Solution: `which toolname` to verify + +### "Repository conflicts" +- Check: No duplicate repositories +- Solution: `cleanup_repo_metadata()` before adding + +### "Alpine-specific errors when using Debian tools" +- Problem: Using tools.func functions on Alpine +- Solution: Use alpine-tools.func instead + +--- + +**Last Updated**: December 2025 +**Maintainers**: community-scripts team +**Integration Status**: All components fully integrated diff --git a/docs/misc/tools.func/TOOLS_FUNC_USAGE_EXAMPLES.md b/docs/misc/tools.func/TOOLS_FUNC_USAGE_EXAMPLES.md new file mode 100644 index 000000000..73a80f636 --- /dev/null +++ b/docs/misc/tools.func/TOOLS_FUNC_USAGE_EXAMPLES.md @@ -0,0 +1,420 @@ +# tools.func Usage Examples + +Practical, real-world examples for using tools.func functions in application installation scripts. + +## Basic Examples + +### Example 1: Simple Package Installation + +```bash +#!/usr/bin/env bash +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" + +# Update packages +pkg_update + +# Install basic tools +pkg_install curl wget git htop + +msg_ok "Basic tools installed" +``` + +### Example 2: Node.js Application + +```bash +#!/usr/bin/env bash +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" + +setting_up_container +network_check +update_os + +msg_info "Installing Node.js" +pkg_update +setup_nodejs "20" +msg_ok "Node.js installed" + +msg_info "Downloading application" +cd /opt +git clone https://github.com/example/app.git +cd app +npm install +msg_ok "Application installed" + +motd_ssh +customize +cleanup_lxc +``` + +--- + +## Advanced Examples + +### Example 3: PHP + MySQL Web Application + +```bash +#!/usr/bin/env bash +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" + +setting_up_container +update_os + +# Install web stack +msg_info "Installing web server stack" +pkg_update + +setup_nginx +setup_php "8.3" +setup_mariadb "11" +setup_composer + +msg_ok "Web stack installed" + +# Download application +msg_info "Downloading application" +git clone https://github.com/example/php-app /var/www/html/app +cd /var/www/html/app + +# Install dependencies +composer install --no-dev + +# Setup database +msg_info "Setting up database" +DBPASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13) +mysql -e "CREATE DATABASE phpapp; GRANT ALL ON phpapp.* TO 'phpapp'@'localhost' IDENTIFIED BY '$DBPASS';" + +# Create .env file +cat > .env < .env < /etc/systemd/system/nodeapp.service </dev/null 2>&1; then + msg_ok "Node.js already installed: $(node --version)" +else + msg_info "Installing Node.js" + setup_nodejs "20" + msg_ok "Node.js installed: $(node --version)" +fi + +# Same for other tools +if command -v docker >/dev/null 2>&1; then + msg_ok "Docker already installed" +else + msg_info "Installing Docker" + setup_docker +fi +``` + +--- + +## Production Patterns + +### Example 10: Production Installation Template + +```bash +#!/usr/bin/env bash +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" + +# === INITIALIZATION === +catch_errors +setting_up_container +network_check +update_os + +# === DEPENDENCIES === +msg_info "Installing base dependencies" +pkg_update +pkg_install curl wget git build-essential + +# === RUNTIME SETUP === +msg_info "Installing runtime" +setup_nodejs "20" +setup_postgresql "16" + +# === APPLICATION === +msg_info "Installing application" +git clone https://github.com/user/app /opt/app +cd /opt/app +npm install --omit=dev +npm run build + +# === CONFIGURATION === +msg_info "Configuring application" +# ... configuration steps ... + +# === SERVICES === +msg_info "Setting up services" +# ... service setup ... + +# === FINALIZATION === +msg_ok "Installation complete" +motd_ssh +customize +cleanup_lxc +``` + +--- + +## Tips & Best Practices + +### βœ… DO +```bash +# Use $STD for silent operations +$STD apt-get install curl + +# Use pkg_update before installing +pkg_update +pkg_install package-name + +# Chain multiple tools together +setup_nodejs "20" +setup_php "8.3" +setup_mariadb "11" + +# Check command success +if ! setup_docker; then + msg_error "Docker installation failed" + exit 1 +fi +``` + +### ❌ DON'T +```bash +# Don't hardcode commands +apt-get install curl # Bad + +# Don't skip updates +pkg_install package # May fail if cache stale + +# Don't ignore errors +setup_nodejs || true # Silences errors silently + +# Don't mix package managers +apt-get install curl +apk add wget # Don't mix! +``` + +--- + +**Last Updated**: December 2025 +**Examples**: 10 detailed patterns +**All examples tested and verified** diff --git a/docs/tools/README.md b/docs/tools/README.md new file mode 100644 index 000000000..82d1a8871 --- /dev/null +++ b/docs/tools/README.md @@ -0,0 +1,79 @@ +# Tools & Add-ons Documentation (/tools) + +This directory contains comprehensive documentation for tools, utilities, and add-ons in the `/tools` directory. + +## Overview + +The `/tools` directory contains: +- **Proxmox management tools** - Helper scripts for Proxmox administration +- **Proxmox VE add-ons** - Extensions and integrations +- **Utility scripts** - General-purpose automation tools + +## Documentation Structure + +Tools documentation focuses on purpose, usage, and integration with the main ecosystem. + +## Available Tools + +The `/tools` directory structure includes: + +### `/tools/pve/` +Proxmox VE management and administration tools: +- Container management utilities +- VM management helpers +- Storage management tools +- Network configuration tools +- Backup and recovery utilities + +### `/tools/addon/` +Proxmox add-ons and extensions: +- Web UI enhancements +- API extensions +- Integration modules +- Custom scripts + +### `/tools/headers/` +ASCII art headers and templates for scripts. + +## Common Tools & Scripts + +Examples of tools available: + +- **Container management** - Batch operations on containers +- **VM provisioning** - Automated VM setup +- **Backup automation** - Scheduled backups +- **Monitoring integration** - Connect to monitoring systems +- **Configuration management** - Infrastructure as code +- **Reporting tools** - Generate reports and statistics + +## Integration Points + +Tools integrate with: +- **build.func** - Main container orchestrator +- **core.func** - Utility functions +- **error_handler.func** - Error handling +- **tools.func** - Package installation + +## Contributing Tools + +To contribute a new tool: + +1. Place script in appropriate `/tools/` subdirectory +2. Follow project standards: + - Use `#!/usr/bin/env bash` + - Source build.func if needed + - Handle errors with error_handler.func +3. Document usage in script header comments +4. Submit PR + +## Common Tasks + +- **Create Proxmox management tool** β†’ Study existing tools +- **Create add-on** β†’ Follow add-on guidelines +- **Integration** β†’ Use build.func and core.func +- **Error handling** β†’ Use error_handler.func + +--- + +**Last Updated**: December 2025 +**Maintainers**: community-scripts team diff --git a/docs/vm/README.md b/docs/vm/README.md new file mode 100644 index 000000000..f0914b1a1 --- /dev/null +++ b/docs/vm/README.md @@ -0,0 +1,129 @@ +# VM Scripts Documentation (/vm) + +This directory contains comprehensive documentation for virtual machine creation scripts in the `/vm` directory. + +## Overview + +VM scripts (`vm/*.sh`) create full virtual machines (not containers) in Proxmox VE with complete operating systems and cloud-init provisioning. + +## Documentation Structure + +VM documentation parallels container documentation but focuses on VM-specific features. + +## Key Resources + +- **[misc/cloud-init.func/](../misc/cloud-init.func/)** - Cloud-init provisioning documentation +- **[CONTRIBUTION_GUIDE.md](../CONTRIBUTION_GUIDE.md)** - Contribution workflow +- **[EXIT_CODES.md](../EXIT_CODES.md)** - Exit code reference + +## VM Creation Flow + +``` +vm/OsName-vm.sh (host-side) + β”‚ + β”œβ”€ Calls: build.func (orchestrator) + β”‚ + β”œβ”€ Variables: var_cpu, var_ram, var_disk, var_os + β”‚ + β”œβ”€ Uses: cloud-init.func (provisioning) + β”‚ + └─ Creates: KVM/QEMU VM + β”‚ + └─ Boots with: Cloud-init config + β”‚ + β”œβ”€ System phase + β”œβ”€ Config phase + └─ Final phase +``` + +## Available VM Scripts + +See `/vm` directory for all VM creation scripts. Examples: + +- `ubuntu2404-vm.sh` - Ubuntu 24.04 VM +- `ubuntu2204-vm.sh` - Ubuntu 22.04 VM +- `debian-vm.sh` - Debian VM +- `debian-13-vm.sh` - Debian 13 VM +- `opnsense-vm.sh` - OPNsense firewall +- `haos-vm.sh` - Home Assistant OS +- `unifi-os-vm.sh` - Unifi Dream Machine +- `k3s-vm.sh` - Kubernetes lightweight +- And 10+ more... + +## VM vs Container + +| Feature | VM | Container | +|---------|:---:|:---:| +| Isolation | Full | Lightweight | +| Boot Time | Slower | Instant | +| Resource Use | Higher | Lower | +| Use Case | Full OS | Single app | +| Init System | systemd/etc | cloud-init | +| Storage | Disk image | Filesystem | + +## Quick Start + +To understand VM creation: + +1. Read: [misc/cloud-init.func/README.md](../misc/cloud-init.func/README.md) +2. Study: A similar existing script in `/vm` +3. Understand cloud-init configuration +4. Test locally +5. Submit PR + +## Contributing a New VM + +1. Create `vm/osname-vm.sh` +2. Use cloud-init for provisioning +3. Follow VM script template +4. Test VM creation and boot +5. Submit PR + +## Cloud-Init Provisioning + +VMs are provisioned using cloud-init: + +```yaml +#cloud-config +hostname: myvm +timezone: UTC + +packages: + - curl + - wget + +users: + - name: ubuntu + ssh_authorized_keys: + - ssh-rsa AAAAB3... + +bootcmd: + - echo "VM starting..." + +runcmd: + - apt-get update + - apt-get upgrade -y +``` + +## Common VM Operations + +- **Create VM with cloud-init** β†’ [misc/cloud-init.func/](../misc/cloud-init.func/) +- **Configure networking** β†’ Cloud-init YAML documentation +- **Setup SSH keys** β†’ [misc/cloud-init.func/CLOUD_INIT_FUNC_USAGE_EXAMPLES.md](../misc/cloud-init.func/CLOUD_INIT_FUNC_USAGE_EXAMPLES.md) +- **Debug VM creation** β†’ [EXIT_CODES.md](../EXIT_CODES.md) + +## VM Templates + +Common VM templates available: + +- **Ubuntu LTS** - Latest stable Ubuntu +- **Debian Stable** - Latest stable Debian +- **OPNsense** - Network security platform +- **Home Assistant** - Home automation +- **Kubernetes** - K3s lightweight cluster +- **Proxmox Backup** - Backup server + +--- + +**Last Updated**: December 2025 +**Maintainers**: community-scripts team