ProxmoxVED/docs/tools.func.md
2025-12-01 10:40:14 +01:00

1284 lines
22 KiB
Markdown

# Tools.func Wiki
A comprehensive collection of helper functions for robust package management and repository management in Debian/Ubuntu-based systems.
---
## 📋 Table of Contents
- [Overview](#overview)
- [Core Helper Functions](#core-helper-functions)
- [Repository Management](#repository-management)
- [Package Management](#package-management)
- [Tool Installation Functions](#tool-installation-functions)
- [GitHub Integration](#github-integration)
- [System Utilities](#system-utilities)
- [Container Setup Functions](#container-setup-functions)
---
## Overview
This function library provides:
- ✅ Automatic retry logic for APT/network failures
- ✅ Unified keyring cleanup from all 3 locations
- ✅ Legacy installation cleanup (nvm, rbenv, rustup)
- ✅ OS-upgrade-safe repository preparation
- ✅ Service pattern matching for multi-version tools
### Usage in Install Scripts
```bash
source /dev/stdin <<< "$FUNCTIONS" # Load from build.func
prepare_repository_setup "mysql"
install_packages_with_retry "mysql-server" "mysql-client"
```
---
## Core Helper Functions
### `cache_installed_version()`
**Purpose**: Caches installed version to avoid repeated checks.
**Parameters**:
- `$1` - Application name
- `$2` - Version string
**Example**:
```bash
cache_installed_version "nodejs" "22.0.0"
```
---
### `get_cached_version()`
**Purpose**: Retrieves cached version of an application.
**Parameters**:
- `$1` - Application name
**Returns**: Version string or empty if not cached
**Example**:
```bash
version=$(get_cached_version "nodejs")
```
---
### `cleanup_tool_keyrings()`
**Purpose**: Removes ALL keyring files for specified tools from all 3 locations.
**Parameters**:
- `$@` - Tool name patterns (supports wildcards)
**Example**:
```bash
cleanup_tool_keyrings "mariadb" "mysql" "postgresql"
```
---
### `stop_all_services()`
**Purpose**: Stops and disables all service instances matching a pattern.
**Parameters**:
- `$@` - Service name patterns (supports wildcards)
**Example**:
```bash
stop_all_services "php*-fpm" "mysql" "mariadb"
```
---
### `verify_tool_version()`
**Purpose**: Verifies installed tool version matches expected version.
**Parameters**:
- `$1` - Tool name
- `$2` - Expected version
- `$3` - Installed version
**Returns**: 0 if match, 1 if mismatch
**Example**:
```bash
verify_tool_version "nodejs" "22" "$(node -v | grep -oP '^v\K[0-9]+')"
```
---
### `cleanup_legacy_install()`
**Purpose**: Removes legacy installation methods (nvm, rbenv, rustup, etc.).
**Parameters**:
- `$1` - Tool name (nodejs, ruby, rust, go)
**Example**:
```bash
cleanup_legacy_install "nodejs" # Removes nvm
```
---
## Repository Management
### `prepare_repository_setup()`
**Purpose**: Unified repository preparation before setup. Cleans up old repos, keyrings, and ensures APT is working.
**Parameters**:
- `$@` - Repository names
**Example**:
```bash
prepare_repository_setup "mariadb" "mysql"
```
---
### `manage_tool_repository()`
**Purpose**: Unified repository management for tools. Handles adding, updating, and verifying tool repositories.
**Parameters**:
- `$1` - Tool name (mariadb, mongodb, nodejs, postgresql, php, mysql)
- `$2` - Version
- `$3` - Repository URL
- `$4` - GPG key URL (optional)
**Supported Tools**: mariadb, mongodb, nodejs, postgresql, php, mysql
**Example**:
```bash
manage_tool_repository "mariadb" "11.4" \
"http://mirror.mariadb.org/repo/11.4" \
"https://mariadb.org/mariadb_release_signing_key.asc"
```
---
### `setup_deb822_repo()`
**Purpose**: Standardized deb822 repository setup with optional architectures. Always runs apt update after repo creation.
**Parameters**:
- `$1` - Repository name
- `$2` - GPG key URL
- `$3` - Repository URL
- `$4` - Suite
- `$5` - Component (default: main)
- `$6` - Architectures (optional)
**Example**:
```bash
setup_deb822_repo "adoptium" \
"https://packages.adoptium.net/artifactory/api/gpg/key/public" \
"https://packages.adoptium.net/artifactory/deb" \
"bookworm" \
"main"
```
---
### `cleanup_old_repo_files()`
**Purpose**: Cleanup old repository files (migration helper for OS upgrades).
**Parameters**:
- `$1` - Application name
**Example**:
```bash
cleanup_old_repo_files "mariadb"
```
---
### `cleanup_orphaned_sources()`
**Purpose**: Cleanup orphaned .sources files that reference missing keyrings. Prevents APT signature verification errors.
**Example**:
```bash
cleanup_orphaned_sources
```
---
### `ensure_apt_working()`
**Purpose**: Ensures APT is in a working state before installing packages.
**Returns**: 0 if APT is working, 1 if critically broken
**Example**:
```bash
ensure_apt_working || return 1
```
---
### `get_fallback_suite()`
**Purpose**: Get fallback suite for repository with comprehensive mapping.
**Parameters**:
- `$1` - Distribution ID (debian, ubuntu)
- `$2` - Distribution codename
- `$3` - Repository base URL
**Returns**: Appropriate suite name
**Example**:
```bash
suite=$(get_fallback_suite "debian" "trixie" "https://repo.example.com")
```
---
## Package Management
### `install_packages_with_retry()`
**Purpose**: Install packages with retry logic (3 attempts with APT refresh).
**Parameters**:
- `$@` - Package names
**Example**:
```bash
install_packages_with_retry "mysql-server" "mysql-client"
```
---
### `upgrade_packages_with_retry()`
**Purpose**: Upgrade specific packages with retry logic.
**Parameters**:
- `$@` - Package names
**Example**:
```bash
upgrade_packages_with_retry "mariadb-server" "mariadb-client"
```
---
### `ensure_dependencies()`
**Purpose**: Ensures dependencies are installed (with apt update caching).
**Parameters**:
- `$@` - Dependency names
**Example**:
```bash
ensure_dependencies "curl" "jq" "git"
```
---
### `is_package_installed()`
**Purpose**: Check if package is installed (faster than dpkg -l | grep).
**Parameters**:
- `$1` - Package name
**Returns**: 0 if installed, 1 if not
**Example**:
```bash
if is_package_installed "nginx"; then
echo "Nginx is installed"
fi
```
---
### `hold_package_version()`
**Purpose**: Hold package version to prevent upgrades.
**Parameters**:
- `$1` - Package name
**Example**:
```bash
hold_package_version "mysql-server"
```
---
### `unhold_package_version()`
**Purpose**: Unhold package version to allow upgrades.
**Parameters**:
- `$1` - Package name
**Example**:
```bash
unhold_package_version "mysql-server"
```
---
## Tool Installation Functions
### `is_tool_installed()`
**Purpose**: Check if tool is already installed and optionally verify exact version.
**Parameters**:
- `$1` - Tool name
- `$2` - Required version (optional)
**Returns**: 0 if installed (with optional version match), 1 if not installed
**Supported Tools**: mariadb, mysql, mongodb, node, php, postgres, ruby, rust, go, clickhouse
**Example**:
```bash
is_tool_installed "mariadb" "11.4" || echo "Not installed"
```
---
### `remove_old_tool_version()`
**Purpose**: Remove old tool version completely (purge + cleanup repos).
**Parameters**:
- `$1` - Tool name
- `$2` - Repository name (optional, defaults to tool name)
**Example**:
```bash
remove_old_tool_version "mariadb" "repository-name"
```
---
### `should_update_tool()`
**Purpose**: Determine if tool update/upgrade is needed.
**Parameters**:
- `$1` - Tool name
- `$2` - Target version
**Returns**: 0 (update needed), 1 (already up-to-date)
**Example**:
```bash
if should_update_tool "mariadb" "11.4"; then
echo "Update needed"
fi
```
---
### `setup_mariadb()`
**Purpose**: Installs or updates MariaDB from official repo.
**Variables**:
- `MARIADB_VERSION` - MariaDB version to install (default: latest)
**Example**:
```bash
MARIADB_VERSION="11.4" setup_mariadb
```
---
### `setup_mysql()`
**Purpose**: Installs or upgrades MySQL and configures APT repo.
**Variables**:
- `MYSQL_VERSION` - MySQL version to install (default: 8.0)
**Features**:
- Handles Debian Trixie libaio1t64 transition
- Auto-fallback to MariaDB if MySQL 8.0 unavailable
**Example**:
```bash
MYSQL_VERSION="8.0" setup_mysql
```
---
### `setup_mongodb()`
**Purpose**: Installs or updates MongoDB to specified major version.
**Variables**:
- `MONGO_VERSION` - MongoDB major version (default: 8.0)
**Example**:
```bash
MONGO_VERSION="7.0" setup_mongodb
```
---
### `setup_postgresql()`
**Purpose**: Installs or upgrades PostgreSQL and optional extensions.
**Variables**:
- `PG_VERSION` - PostgreSQL major version (default: 16)
- `PG_MODULES` - Comma-separated list of extensions
**Example**:
```bash
PG_VERSION="16" PG_MODULES="postgis,contrib" setup_postgresql
```
---
### `setup_nodejs()`
**Purpose**: Installs Node.js and optional global modules.
**Variables**:
- `NODE_VERSION` - Node.js version (default: 22)
- `NODE_MODULE` - Comma-separated list of global modules
**Example**:
```bash
NODE_VERSION="22" NODE_MODULE="yarn,@vue/cli@5.0.0" setup_nodejs
```
---
### `setup_php()`
**Purpose**: Installs PHP with selected modules and configures Apache/FPM support.
**Variables**:
- `PHP_VERSION` - PHP version (default: 8.4)
- `PHP_MODULE` - Additional comma-separated modules
- `PHP_APACHE` - Set YES to enable PHP with Apache
- `PHP_FPM` - Set YES to enable PHP-FPM
- `PHP_MEMORY_LIMIT` - Memory limit (default: 512M)
- `PHP_UPLOAD_MAX_FILESIZE` - Upload max filesize (default: 128M)
- `PHP_POST_MAX_SIZE` - Post max size (default: 128M)
- `PHP_MAX_EXECUTION_TIME` - Max execution time (default: 300)
**Example**:
```bash
PHP_VERSION="8.4" PHP_MODULE="redis,imagick" PHP_FPM="YES" setup_php
```
---
### `setup_java()`
**Purpose**: Installs Temurin JDK via Adoptium APT repository.
**Variables**:
- `JAVA_VERSION` - Temurin JDK version (default: 21)
**Example**:
```bash
JAVA_VERSION="21" setup_java
```
---
### `setup_ruby()`
**Purpose**: Installs rbenv and ruby-build, installs Ruby and optionally Rails.
**Variables**:
- `RUBY_VERSION` - Ruby version (default: 3.4.4)
- `RUBY_INSTALL_RAILS` - true/false to install Rails (default: true)
**Example**:
```bash
RUBY_VERSION="3.4.4" RUBY_INSTALL_RAILS="true" setup_ruby
```
---
### `setup_rust()`
**Purpose**: Installs Rust toolchain and optional global crates.
**Variables**:
- `RUST_TOOLCHAIN` - Rust toolchain (default: stable)
- `RUST_CRATES` - Comma-separated list of crates
**Example**:
```bash
RUST_TOOLCHAIN="stable" RUST_CRATES="cargo-edit,wasm-pack@0.12.1" setup_rust
```
---
### `setup_go()`
**Purpose**: Installs Go (Golang) from official tarball.
**Variables**:
- `GO_VERSION` - Go version (default: latest)
**Example**:
```bash
GO_VERSION="1.22.2" setup_go
```
---
### `setup_composer()`
**Purpose**: Installs or updates Composer globally (robust, idempotent).
**Features**:
- Installs to /usr/local/bin/composer
- Removes old binaries/symlinks
- Ensures /usr/local/bin is in PATH
- Auto-updates to latest version
**Example**:
```bash
setup_composer
```
---
### `setup_uv()`
**Purpose**: Installs or upgrades uv (Python package manager) from GitHub releases.
**Variables**:
- `USE_UVX` - Set YES to install uvx wrapper (default: NO)
- `PYTHON_VERSION` - Optional Python version to install via uv
**Example**:
```bash
USE_UVX="YES" PYTHON_VERSION="3.12" setup_uv
```
---
### `setup_yq()`
**Purpose**: Installs or updates yq (mikefarah/yq - Go version).
**Example**:
```bash
setup_yq
```
---
### `setup_ffmpeg()`
**Purpose**: Installs FFmpeg from source or prebuilt binary.
**Variables**:
- `FFMPEG_VERSION` - FFmpeg version (default: latest)
- `FFMPEG_TYPE` - Build profile: minimal, medium, full, binary (default: full)
**Example**:
```bash
FFMPEG_VERSION="n7.1.1" FFMPEG_TYPE="full" setup_ffmpeg
```
---
### `setup_imagemagick()`
**Purpose**: Installs ImageMagick 7 from source.
**Example**:
```bash
setup_imagemagick
```
---
### `setup_gs()`
**Purpose**: Installs or updates Ghostscript (gs) from source.
**Example**:
```bash
setup_gs
```
---
### `setup_hwaccel()`
**Purpose**: Sets up Hardware Acceleration for Intel/AMD/NVIDIA GPUs.
**Example**:
```bash
setup_hwaccel
```
---
### `setup_clickhouse()`
**Purpose**: Installs or upgrades ClickHouse database server.
**Variables**:
- `CLICKHOUSE_VERSION` - ClickHouse version (default: latest)
**Example**:
```bash
CLICKHOUSE_VERSION="latest" setup_clickhouse
```
---
### `setup_adminer()`
**Purpose**: Installs Adminer (supports Debian/Ubuntu and Alpine).
**Example**:
```bash
setup_adminer
```
---
## GitHub Integration
### `check_for_gh_release()`
**Purpose**: Checks for new GitHub release (latest tag).
**Parameters**:
- `$1` - Application name
- `$2` - GitHub repository (user/repo)
- `$3` - Optional pinned version
**Returns**: 0 if update available, 1 if up-to-date
**Global Variables Set**:
- `CHECK_UPDATE_RELEASE` - Latest release tag
**Example**:
```bash
if check_for_gh_release "flaresolverr" "FlareSolverr/FlareSolverr"; then
echo "Update available: $CHECK_UPDATE_RELEASE"
fi
```
---
### `fetch_and_deploy_gh_release()`
**Purpose**: Downloads and deploys latest GitHub release.
**Parameters**:
- `$1` - Application name
- `$2` - GitHub repository (user/repo)
- `$3` - Mode: tarball, binary, prebuild, singlefile (default: tarball)
- `$4` - Version (default: latest)
- `$5` - Target directory (default: /opt/app)
- `$6` - Asset filename/pattern (required for prebuild/singlefile)
**Modes**:
- `tarball` - Source code tarball (.tar.gz)
- `binary` - .deb package install (arch-dependent)
- `prebuild` - Prebuilt .tar.gz archive
- `singlefile` - Standalone binary (chmod +x)
**Example**:
```bash
# Source tarball
fetch_and_deploy_gh_release "myapp" "myuser/myapp"
# Binary .deb
fetch_and_deploy_gh_release "myapp" "myuser/myapp" "binary"
# Prebuilt archive
fetch_and_deploy_gh_release "hanko" "teamhanko/hanko" "prebuild" \
"latest" "/opt/hanko" "hanko_Linux_x86_64.tar.gz"
# Single binary
fetch_and_deploy_gh_release "argus" "release-argus/Argus" "singlefile" \
"0.26.3" "/opt/argus" "Argus-.*linux-amd64"
```
---
### `github_api_call()`
**Purpose**: GitHub API call with authentication and rate limit handling.
**Parameters**:
- `$1` - API URL
- `$2` - Output file (default: /dev/stdout)
**Environment Variables**:
- `GITHUB_TOKEN` - Optional GitHub token for higher rate limits
**Example**:
```bash
github_api_call "https://api.github.com/repos/user/repo/releases/latest" "/tmp/release.json"
```
---
### `get_latest_github_release()`
**Purpose**: Get latest GitHub release version.
**Parameters**:
- `$1` - GitHub repository (user/repo)
- `$2` - Strip 'v' prefix (default: true)
**Returns**: Version string
**Example**:
```bash
version=$(get_latest_github_release "nodejs/node")
```
---
## System Utilities
### `get_os_info()`
**Purpose**: Get OS information (cached for performance).
**Parameters**:
- `$1` - Field: id, codename, version, version_id, all (default: all)
**Returns**: Requested OS information
**Example**:
```bash
os_id=$(get_os_info id)
os_codename=$(get_os_info codename)
```
---
### `is_debian()`, `is_ubuntu()`, `is_alpine()`
**Purpose**: Check if running on specific OS.
**Returns**: 0 if match, 1 if not
**Example**:
```bash
if is_debian; then
echo "Running on Debian"
fi
```
---
### `get_os_version_major()`
**Purpose**: Get Debian/Ubuntu major version.
**Returns**: Major version number
**Example**:
```bash
major_version=$(get_os_version_major)
```
---
### `get_system_arch()`
**Purpose**: Get system architecture (normalized).
**Parameters**:
- `$1` - Architecture type: dpkg, uname, both (default: both)
**Returns**: Architecture string (amd64, arm64)
**Example**:
```bash
arch=$(get_system_arch)
```
---
### `version_gt()`
**Purpose**: Smart version comparison.
**Parameters**:
- `$1` - Version 1
- `$2` - Version 2
**Returns**: 0 if version 1 > version 2
**Example**:
```bash
if version_gt "2.0.0" "1.5.0"; then
echo "Version 2.0.0 is greater"
fi
```
---
### `is_lts_version()`
**Purpose**: Check if running on LTS version.
**Returns**: 0 if LTS, 1 if not
**Example**:
```bash
if is_lts_version; then
echo "Running on LTS"
fi
```
---
### `get_parallel_jobs()`
**Purpose**: Get optimal number of parallel jobs (cached).
**Returns**: Number of parallel jobs based on CPU and memory
**Example**:
```bash
jobs=$(get_parallel_jobs)
make -j"$jobs"
```
---
### `is_apt_locked()`
**Purpose**: Check if package manager is locked.
**Returns**: 0 if locked, 1 if not
**Example**:
```bash
if is_apt_locked; then
echo "APT is locked"
fi
```
---
### `wait_for_apt()`
**Purpose**: Wait for apt to be available.
**Parameters**:
- `$1` - Max wait time in seconds (default: 300)
**Example**:
```bash
wait_for_apt 600 # Wait up to 10 minutes
```
---
### `download_file()`
**Purpose**: Download file with retry logic and progress.
**Parameters**:
- `$1` - URL
- `$2` - Output path
- `$3` - Max retries (default: 3)
- `$4` - Show progress (default: false)
**Example**:
```bash
download_file "https://example.com/file.tar.gz" "/tmp/file.tar.gz" 3 true
```
---
### `create_temp_dir()`
**Purpose**: Create temporary directory with automatic cleanup.
**Returns**: Temporary directory path
**Example**:
```bash
tmp_dir=$(create_temp_dir)
# Directory is automatically cleaned up on exit
```
---
### `safe_service_restart()`
**Purpose**: Safe service restart with verification.
**Parameters**:
- `$1` - Service name
**Example**:
```bash
safe_service_restart "nginx"
```
---
### `enable_and_start_service()`
**Purpose**: Enable and start service (with error handling).
**Parameters**:
- `$1` - Service name
**Example**:
```bash
enable_and_start_service "postgresql"
```
---
### `is_service_enabled()`, `is_service_running()`
**Purpose**: Check if service is enabled/running.
**Parameters**:
- `$1` - Service name
**Returns**: 0 if yes, 1 if no
**Example**:
```bash
if is_service_running "nginx"; then
echo "Nginx is running"
fi
```
---
### `create_self_signed_cert()`
**Purpose**: Creates and installs self-signed certificates.
**Parameters**:
- `$1` - Application name (optional, defaults to $APPLICATION)
**Example**:
```bash
create_self_signed_cert "myapp"
```
---
### `import_local_ip()`
**Purpose**: Loads LOCAL_IP from persistent store or detects if missing.
**Global Variables Set**:
- `LOCAL_IP` - Local IP address
**Example**:
```bash
import_local_ip
echo "Local IP: $LOCAL_IP"
```
---
### `setup_local_ip_helper()`
**Purpose**: Installs a local IP updater script using networkd-dispatcher.
**Example**:
```bash
setup_local_ip_helper
```
---
### `ensure_usr_local_bin_persist()`
**Purpose**: Ensures /usr/local/bin is permanently in system PATH.
**Example**:
```bash
ensure_usr_local_bin_persist
```
---
### `download_with_progress()`
**Purpose**: Downloads file with optional progress indicator using pv.
**Parameters**:
- `$1` - URL
- `$2` - Destination path
**Example**:
```bash
download_with_progress "https://example.com/file.tar.gz" "/tmp/file.tar.gz"
```
---
### `verify_gpg_fingerprint()`
**Purpose**: GPG key fingerprint verification.
**Parameters**:
- `$1` - Key file path
- `$2` - Expected fingerprint
**Example**:
```bash
verify_gpg_fingerprint "/tmp/key.gpg" "ABCD1234..."
```
---
### `debug_log()`
**Purpose**: Debug logging (only if DEBUG=1).
**Parameters**:
- `$@` - Message to log
**Example**:
```bash
DEBUG=1 debug_log "This is a debug message"
```
---
### `start_timer()`, `end_timer()`
**Purpose**: Performance timing helpers.
**Example**:
```bash
start_time=$(start_timer)
# ... do something ...
end_timer "$start_time" "Operation"
```
---
## Container Setup Functions
### `color()`
**Purpose**: Sets up color and formatting variables for terminal output.
**Example**:
```bash
color
echo -e "${GN}Success${CL}"
```
---
### `verb_ip6()`
**Purpose**: Enables or disables IPv6 based on DISABLEIPV6 variable.
**Variables**:
- `DISABLEIPV6` - Set "yes" to disable IPv6
**Example**:
```bash
DISABLEIPV6="yes" verb_ip6
```
---
### `catch_errors()`
**Purpose**: Sets up error handling for the script.
**Example**:
```bash
catch_errors
```
---
### `error_handler()`
**Purpose**: Handles errors that occur during script execution.
**Parameters**:
- `$1` - Line number
- `$2` - Command that failed
**Example**:
```bash
error_handler 42 "ls non_existent_file"
```
---
### `spinner()`
**Purpose**: Displays a rotating spinner animation.
**Example**:
```bash
spinner &
SPINNER_PID=$!
```
---
### `msg_info()`, `msg_ok()`, `msg_error()`
**Purpose**: Display messages with different statuses.
**Parameters**:
- `$1` - Message text
**Example**:
```bash
msg_info "Installing packages..."
msg_ok "Installation complete"
msg_error "Installation failed"
```
---
### `setting_up_container()`
**Purpose**: Sets up container OS, configures locale, timezone, and network.
**Example**:
```bash
setting_up_container
```
---
### `network_check()`
**Purpose**: Verifies internet connectivity via IPv4 and IPv6.
**Example**:
```bash
network_check
```
---
### `update_os()`
**Purpose**: Updates the container's OS using apt-get.
**Variables**:
- `CACHER` - Enable package caching proxy
**Example**:
```bash
update_os
```
---
### `motd_ssh()`
**Purpose**: Modifies message of the day (MOTD) and SSH settings.
**Example**:
```bash
motd_ssh
```
---
### `customize()`
**Purpose**: Customizes the container by enabling auto-login and setting up SSH keys.
**Example**:
```bash
customize
```
---
## Best Practices
### Version Management
Always cache versions after installation:
```bash
setup_nodejs
cache_installed_version "nodejs" "$NODE_VERSION"
```
### Error Handling
Always check return codes:
```bash
if ! install_packages_with_retry "nginx"; then
msg_error "Failed to install nginx"
return 1
fi
```
### Repository Setup
Always prepare repositories before installation:
```bash
prepare_repository_setup "mariadb" || return 1
manage_tool_repository "mariadb" "11.4" "$REPO_URL" "$GPG_URL" || return 1
```
### APT Safety
Always ensure APT is working before operations:
```bash
ensure_apt_working || return 1
install_packages_with_retry "package-name"
```
---
## Notes
- All functions use `$STD` variable for silent execution
- Functions support both fresh installs and upgrades
- Automatic fallback mechanisms for newer OS versions
- Version caching prevents redundant installations
- Comprehensive error handling and retry logic
---
## License
This documentation is part of the community-scripts project.
---
## Contributing
Contributions are welcome! Please follow the existing code style and add appropriate documentation for new functions.