2025-05-05 15:47:43 +02:00
#!/bin/bash
2025-05-15 15:18:41 +02:00
2025-10-22 06:25:26 -07:00
# ==============================================================================
# HELPER FUNCTIONS FOR PACKAGE MANAGEMENT
# ==============================================================================
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
#
# This file provides unified helper functions for robust package installation
# and repository management across Debian/Ubuntu OS upgrades.
#
# Key Features:
# - Automatic retry logic for transient 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:
# source /dev/stdin <<< "$FUNCTIONS" # Load from build.func
# prepare_repository_setup "mysql"
# install_packages_with_retry "mysql-server" "mysql-client"
#
# Quick Reference (Core Helpers):
# cleanup_tool_keyrings() - Remove keyrings from all 3 locations
# stop_all_services() - Stop services by pattern (e.g. "php*-fpm")
# verify_tool_version() - Validate installed version matches expected
# cleanup_legacy_install() - Remove nvm, rbenv, rustup, etc.
# prepare_repository_setup() - Cleanup repos + keyrings + validate APT
# install_packages_with_retry() - Install with 3 retries and APT refresh
# upgrade_packages_with_retry() - Upgrade with 3 retries and APT refresh
#
# ==============================================================================
2025-10-22 06:25:26 -07:00
# ------------------------------------------------------------------------------
# Cache installed version to avoid repeated checks
# ------------------------------------------------------------------------------
cache_installed_version( ) {
local app = " $1 "
local version = " $2 "
mkdir -p /var/cache/app-versions
echo " $version " >" /var/cache/app-versions/ ${ app } _version.txt "
}
get_cached_version( ) {
local app = " $1 "
mkdir -p /var/cache/app-versions
if [ [ -f " /var/cache/app-versions/ ${ app } _version.txt " ] ] ; then
cat " /var/cache/app-versions/ ${ app } _version.txt "
return 0
fi
return 0
}
# ------------------------------------------------------------------------------
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Clean up ALL keyring locations for a tool (unified helper)
# Usage: cleanup_tool_keyrings "mariadb" "mysql" "postgresql"
# ------------------------------------------------------------------------------
cleanup_tool_keyrings( ) {
local tool_patterns = ( " $@ " )
for pattern in " ${ tool_patterns [@] } " ; do
rm -f /usr/share/keyrings/${ pattern } *.gpg \
/etc/apt/keyrings/${ pattern } *.gpg \
/etc/apt/trusted.gpg.d/${ pattern } *.gpg 2>/dev/null || true
done
}
# ------------------------------------------------------------------------------
# Stop and disable all service instances matching a pattern
# Usage: stop_all_services "php*-fpm" "mysql" "mariadb"
# ------------------------------------------------------------------------------
stop_all_services( ) {
local service_patterns = ( " $@ " )
for pattern in " ${ service_patterns [@] } " ; do
2025-12-07 21:30:23 +01:00
# Find all matching services (grep || true to handle no matches)
local services
services = $( systemctl list-units --type= service --all 2>/dev/null |
grep -oE " ${ pattern } [^ ]*\.service " 2>/dev/null | sort -u) || true
Three-tier defaults system | security improvements | error_handler | improved logging | improved container creation | improved architecture (#9540)
* Refactor Core
Refactored misc/alpine-install.func to improve error handling, network checks, and MOTD setup. Added misc/alpine-tools.func and misc/error_handler.func for modular tool installation and error management. Enhanced misc/api.func with detailed exit code explanations and telemetry functions. Updated misc/core.func for better initialization, validation, and execution helpers. Removed misc/create_lxc.sh as part of cleanup.
* Delete config-file.func
* Update install.func
* Refactor stop_all_services function and variable names
Refactor service stopping logic and improve variable handling
* Refactor installation script and update copyright
Updated copyright information and adjusted package installation commands. Enhanced IPv6 disabling logic and improved container customization process.
* Update install.func
* Update license comment format in install.func
* Refactor IPv6 handling and enhance MOTD and SSH
Refactor IPv6 handling and update OS function. Enhance MOTD with additional details and configure SSH settings.
* big core refactor
* Enhance IPv6 configuration menu options
Updated IPv6 Address Management menu options for clarity and added a new option for fully disabling IPv6.
* Update default Node.js version to 24 LTS
* Update misc/alpine-tools.func
Co-authored-by: Michel Roegl-Brunner <73236783+michelroegl-brunner@users.noreply.github.com>
* indention
* remove debugf and duplicate codes
* Update whiptail backtitles and error codes
Removed '[dev]' from whiptail --backtitle strings for consistency. Refactored custom exit codes in build.func and error_handler.func: updated Proxmox error codes, shifted MySQL/MariaDB codes to 260-263, and removed unused MongoDB code. Updated error descriptions to match new codes.
* comments
* Refactor error handling and clean up debug comments
Standardized bash variable checks, removed unnecessary debug and commented code, and clarified error handling logic in container build and setup scripts. These changes improve code readability and maintainability without altering functional behavior.
* Update build.func
* feat: Improve LXC network checks and LINSTOR storage handling
Enhanced LXC container network setup to check for both IPv4 and IPv6 addresses, added connectivity (ping) tests, and provided troubleshooting tips on failure. Updated storage validation to support LINSTOR, including cluster connectivity checks and special handling for LINSTOR template storage.
---------
Co-authored-by: Michel Roegl-Brunner <73236783+michelroegl-brunner@users.noreply.github.com>
2025-12-04 07:52:18 +01:00
2025-12-07 21:30:23 +01:00
if [ [ -n " $services " ] ] ; then
Three-tier defaults system | security improvements | error_handler | improved logging | improved container creation | improved architecture (#9540)
* Refactor Core
Refactored misc/alpine-install.func to improve error handling, network checks, and MOTD setup. Added misc/alpine-tools.func and misc/error_handler.func for modular tool installation and error management. Enhanced misc/api.func with detailed exit code explanations and telemetry functions. Updated misc/core.func for better initialization, validation, and execution helpers. Removed misc/create_lxc.sh as part of cleanup.
* Delete config-file.func
* Update install.func
* Refactor stop_all_services function and variable names
Refactor service stopping logic and improve variable handling
* Refactor installation script and update copyright
Updated copyright information and adjusted package installation commands. Enhanced IPv6 disabling logic and improved container customization process.
* Update install.func
* Update license comment format in install.func
* Refactor IPv6 handling and enhance MOTD and SSH
Refactor IPv6 handling and update OS function. Enhance MOTD with additional details and configure SSH settings.
* big core refactor
* Enhance IPv6 configuration menu options
Updated IPv6 Address Management menu options for clarity and added a new option for fully disabling IPv6.
* Update default Node.js version to 24 LTS
* Update misc/alpine-tools.func
Co-authored-by: Michel Roegl-Brunner <73236783+michelroegl-brunner@users.noreply.github.com>
* indention
* remove debugf and duplicate codes
* Update whiptail backtitles and error codes
Removed '[dev]' from whiptail --backtitle strings for consistency. Refactored custom exit codes in build.func and error_handler.func: updated Proxmox error codes, shifted MySQL/MariaDB codes to 260-263, and removed unused MongoDB code. Updated error descriptions to match new codes.
* comments
* Refactor error handling and clean up debug comments
Standardized bash variable checks, removed unnecessary debug and commented code, and clarified error handling logic in container build and setup scripts. These changes improve code readability and maintainability without altering functional behavior.
* Update build.func
* feat: Improve LXC network checks and LINSTOR storage handling
Enhanced LXC container network setup to check for both IPv4 and IPv6 addresses, added connectivity (ping) tests, and provided troubleshooting tips on failure. Updated storage validation to support LINSTOR, including cluster connectivity checks and special handling for LINSTOR template storage.
---------
Co-authored-by: Michel Roegl-Brunner <73236783+michelroegl-brunner@users.noreply.github.com>
2025-12-04 07:52:18 +01:00
while read -r service; do
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
$STD systemctl stop " $service " 2>/dev/null || true
$STD systemctl disable " $service " 2>/dev/null || true
2025-12-07 21:30:23 +01:00
done <<< " $services "
fi
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
done
2025-11-10 13:58:04 +01:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
}
# ------------------------------------------------------------------------------
# Verify installed tool version matches expected version
# Returns: 0 if match, 1 if mismatch (with warning)
# Usage: verify_tool_version "nodejs" "22" "$(node -v | grep -oP '^v\K[0-9]+')"
# ------------------------------------------------------------------------------
verify_tool_version( ) {
local tool_name = " $1 "
local expected_version = " $2 "
local installed_version = " $3 "
# Extract major version for comparison
local expected_major = " ${ expected_version %%.* } "
local installed_major = " ${ installed_version %%.* } "
if [ [ " $installed_major " != " $expected_major " ] ] ; then
msg_warn " $tool_name version mismatch: expected $expected_version , got $installed_version "
return 1
fi
return 0
}
# ------------------------------------------------------------------------------
# Clean up legacy installation methods (nvm, rbenv, rustup, etc.)
# Usage: cleanup_legacy_install "nodejs" -> removes nvm
# ------------------------------------------------------------------------------
cleanup_legacy_install( ) {
local tool_name = " $1 "
case " $tool_name " in
nodejs | node)
if [ [ -d " $HOME /.nvm " ] ] ; then
msg_info "Removing legacy nvm installation"
rm -rf " $HOME /.nvm " " $HOME /.npm " " $HOME /.bower " " $HOME /.config/yarn " 2>/dev/null || true
sed -i '/NVM_DIR/d' " $HOME /.bashrc " " $HOME /.profile " 2>/dev/null || true
msg_ok "Legacy nvm installation removed"
fi
; ;
ruby)
if [ [ -d " $HOME /.rbenv " ] ] ; then
msg_info "Removing legacy rbenv installation"
rm -rf " $HOME /.rbenv " 2>/dev/null || true
sed -i '/rbenv/d' " $HOME /.bashrc " " $HOME /.profile " 2>/dev/null || true
msg_ok "Legacy rbenv installation removed"
fi
; ;
rust)
if [ [ -d " $HOME /.cargo " ] ] || [ [ -d " $HOME /.rustup " ] ] ; then
msg_info "Removing legacy rustup installation"
rm -rf " $HOME /.cargo " " $HOME /.rustup " 2>/dev/null || true
sed -i '/cargo/d' " $HOME /.bashrc " " $HOME /.profile " 2>/dev/null || true
msg_ok "Legacy rustup installation removed"
fi
; ;
go | golang)
if [ [ -d " $HOME /go " ] ] ; then
msg_info "Removing legacy Go workspace"
# Keep user code, just remove GOPATH env
sed -i '/GOPATH/d' " $HOME /.bashrc " " $HOME /.profile " 2>/dev/null || true
msg_ok "Legacy Go workspace cleaned"
fi
; ;
esac
}
# ------------------------------------------------------------------------------
# Unified repository preparation before setup
# Cleans up old repos, keyrings, and ensures APT is working
# Usage: prepare_repository_setup "mariadb" "mysql"
# ------------------------------------------------------------------------------
prepare_repository_setup( ) {
local repo_names = ( " $@ " )
# Clean up all old repository files
for repo in " ${ repo_names [@] } " ; do
cleanup_old_repo_files " $repo "
done
# Clean up all keyrings
cleanup_tool_keyrings " ${ repo_names [@] } "
# Ensure APT is in working state
ensure_apt_working || return 1
return 0
}
# ------------------------------------------------------------------------------
# Install packages with retry logic
# Usage: install_packages_with_retry "mysql-server" "mysql-client"
# ------------------------------------------------------------------------------
install_packages_with_retry( ) {
local packages = ( " $@ " )
local max_retries = 2
local retry = 0
while [ [ $retry -le $max_retries ] ] ; do
2026-01-09 21:19:47 +01:00
if DEBIAN_FRONTEND = noninteractive $STD apt install -y \
-o Dpkg::Options::= "--force-confdef" \
-o Dpkg::Options::= "--force-confold" \
" ${ packages [@] } " 2>/dev/null; then
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
return 0
fi
retry = $(( retry + 1 ))
if [ [ $retry -le $max_retries ] ] ; then
msg_warn " Package installation failed, retrying ( $retry / $max_retries )... "
sleep 2
2025-12-05 09:17:19 +01:00
# Fix any interrupted dpkg operations before retry
$STD dpkg --configure -a 2>/dev/null || true
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
$STD apt update 2>/dev/null || true
fi
done
return 1
}
# ------------------------------------------------------------------------------
# Upgrade specific packages with retry logic
# Usage: upgrade_packages_with_retry "mariadb-server" "mariadb-client"
# ------------------------------------------------------------------------------
upgrade_packages_with_retry( ) {
local packages = ( " $@ " )
local max_retries = 2
local retry = 0
while [ [ $retry -le $max_retries ] ] ; do
2026-01-09 21:19:47 +01:00
if DEBIAN_FRONTEND = noninteractive $STD apt install --only-upgrade -y \
-o Dpkg::Options::= "--force-confdef" \
-o Dpkg::Options::= "--force-confold" \
" ${ packages [@] } " 2>/dev/null; then
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
return 0
fi
retry = $(( retry + 1 ))
if [ [ $retry -le $max_retries ] ] ; then
msg_warn " Package upgrade failed, retrying ( $retry / $max_retries )... "
sleep 2
2025-12-05 09:17:19 +01:00
# Fix any interrupted dpkg operations before retry
$STD dpkg --configure -a 2>/dev/null || true
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
$STD apt update 2>/dev/null || true
fi
done
return 1
}
# ------------------------------------------------------------------------------
# Check if tool is already installed and optionally verify exact version
# Returns: 0 if installed (with optional version match), 1 if not installed
# Usage: is_tool_installed "mariadb" "11.4" || echo "Not installed"
# ------------------------------------------------------------------------------
is_tool_installed( ) {
local tool_name = " $1 "
local required_version = " ${ 2 :- } "
local installed_version = ""
case " $tool_name " in
mariadb)
if command -v mariadb >/dev/null 2>& 1; then
installed_version = $( mariadb --version 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1)
fi
; ;
mysql)
if command -v mysql >/dev/null 2>& 1; then
installed_version = $( mysql --version 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1)
fi
; ;
mongodb | mongod)
if command -v mongod >/dev/null 2>& 1; then
installed_version = $( mongod --version 2>/dev/null | awk '/db version/{print $3}' | cut -d. -f1,2)
fi
; ;
node | nodejs)
if command -v node >/dev/null 2>& 1; then
installed_version = $( node -v 2>/dev/null | grep -oP '^v\K[0-9]+' )
fi
; ;
php)
if command -v php >/dev/null 2>& 1; then
installed_version = $( php -v 2>/dev/null | awk '/^PHP/{print $2}' | cut -d. -f1,2)
fi
; ;
postgres | postgresql)
if command -v psql >/dev/null 2>& 1; then
installed_version = $( psql --version 2>/dev/null | awk '{print $3}' | cut -d. -f1)
fi
; ;
ruby)
if command -v ruby >/dev/null 2>& 1; then
installed_version = $( ruby --version 2>/dev/null | awk '{print $2}' | cut -d. -f1,2)
fi
; ;
rust | rustc)
if command -v rustc >/dev/null 2>& 1; then
installed_version = $( rustc --version 2>/dev/null | awk '{print $2}' )
fi
; ;
go | golang)
if command -v go >/dev/null 2>& 1; then
installed_version = $( go version 2>/dev/null | awk '{print $3}' | sed 's/go//' )
fi
; ;
clickhouse)
if command -v clickhouse >/dev/null 2>& 1; then
installed_version = $( clickhouse --version 2>/dev/null | awk '{print $2}' )
fi
; ;
esac
if [ [ -z " $installed_version " ] ] ; then
return 1 # Not installed
fi
if [ [ -n " $required_version " && " $installed_version " != " $required_version " ] ] ; then
echo " $installed_version "
return 1 # Version mismatch
fi
echo " $installed_version "
return 0 # Installed and version matches (if specified)
}
# ------------------------------------------------------------------------------
# Remove old tool version completely (purge + cleanup repos)
# Usage: remove_old_tool_version "mariadb" "repository-name"
# ------------------------------------------------------------------------------
remove_old_tool_version( ) {
local tool_name = " $1 "
local repo_name = " ${ 2 :- $tool_name } "
case " $tool_name " in
mariadb)
stop_all_services "mariadb"
$STD apt purge -y 'mariadb*' >/dev/null 2>& 1 || true
cleanup_tool_keyrings "mariadb"
; ;
mysql)
stop_all_services "mysql"
$STD apt purge -y 'mysql*' >/dev/null 2>& 1 || true
rm -rf /var/lib/mysql 2>/dev/null || true
cleanup_tool_keyrings "mysql"
; ;
mongodb)
stop_all_services "mongod"
$STD apt purge -y 'mongodb*' >/dev/null 2>& 1 || true
rm -rf /var/lib/mongodb 2>/dev/null || true
cleanup_tool_keyrings "mongodb"
; ;
node | nodejs)
$STD apt purge -y nodejs npm >/dev/null 2>& 1 || true
# Clean up npm global modules
if command -v npm >/dev/null 2>& 1; then
2025-12-18 18:38:08 +01:00
npm list -g 2>/dev/null | grep -oE '^ \S+' | awk '{print $1}' 2>/dev/null | while read -r module; do
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
npm uninstall -g " $module " >/dev/null 2>& 1 || true
2025-12-18 18:38:08 +01:00
done || true
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
fi
cleanup_legacy_install "nodejs"
cleanup_tool_keyrings "nodesource"
; ;
php)
stop_all_services "php.*-fpm"
$STD apt purge -y 'php*' >/dev/null 2>& 1 || true
rm -rf /etc/php 2>/dev/null || true
cleanup_tool_keyrings "deb.sury.org-php" "php"
; ;
postgresql)
stop_all_services "postgresql"
$STD apt purge -y 'postgresql*' >/dev/null 2>& 1 || true
# Keep data directory for safety (can be removed manually if needed)
# rm -rf /var/lib/postgresql 2>/dev/null || true
cleanup_tool_keyrings "postgresql" "pgdg"
; ;
java)
$STD apt purge -y 'temurin*' 'adoptium*' 'openjdk*' >/dev/null 2>& 1 || true
cleanup_tool_keyrings "adoptium"
; ;
ruby)
cleanup_legacy_install "ruby"
$STD apt purge -y 'ruby*' >/dev/null 2>& 1 || true
; ;
rust)
cleanup_legacy_install "rust"
; ;
go | golang)
rm -rf /usr/local/go 2>/dev/null || true
cleanup_legacy_install "golang"
; ;
clickhouse)
stop_all_services "clickhouse-server"
$STD apt purge -y 'clickhouse*' >/dev/null 2>& 1 || true
rm -rf /var/lib/clickhouse 2>/dev/null || true
cleanup_tool_keyrings "clickhouse"
; ;
esac
# Clean up old repository files (both .list and .sources)
cleanup_old_repo_files " $repo_name "
return 0
}
# ------------------------------------------------------------------------------
# Determine if tool update/upgrade is needed
# Returns: 0 (update needed), 1 (already up-to-date)
# Usage: if should_update_tool "mariadb" "11.4"; then ... fi
# ------------------------------------------------------------------------------
should_update_tool( ) {
local tool_name = " $1 "
local target_version = " $2 "
local current_version = ""
# Get currently installed version
current_version = $( is_tool_installed " $tool_name " 2>/dev/null) || return 0 # Not installed = needs install
# If versions are identical, no update needed
if [ [ " $current_version " = = " $target_version " ] ] ; then
return 1 # No update needed
fi
return 0 # Update needed
}
# ---------------------– ----------------------------------------------------------
# Unified repository management for tools
# Handles adding, updating, and verifying tool repositories
# Usage: manage_tool_repository "mariadb" "11.4" "https://repo..." "GPG_key_url"
# Supports: mariadb, mongodb, nodejs, postgresql, php, mysql
# ------------------------------------------------------------------------------
manage_tool_repository( ) {
local tool_name = " $1 "
local version = " $2 "
local repo_url = " $3 "
local gpg_key_url = " ${ 4 :- } "
local distro_id repo_component suite
distro_id = $( awk -F= '/^ID=/{print $2}' /etc/os-release | tr -d '"' )
case " $tool_name " in
mariadb)
if [ [ -z " $repo_url " || -z " $gpg_key_url " ] ] ; then
msg_error "MariaDB repository requires repo_url and gpg_key_url"
return 1
fi
# Clean old repos first
cleanup_old_repo_files "mariadb"
# Get suite for fallback handling
local distro_codename
distro_codename = $( awk -F= '/^VERSION_CODENAME=/{print $2}' /etc/os-release)
suite = $( get_fallback_suite " $distro_id " " $distro_codename " " $repo_url / $distro_id " )
# Setup new repository using deb822 format
2025-11-07 02:49:16 -08:00
setup_deb822_repo \
"mariadb" \
" $gpg_key_url " \
" $repo_url / $distro_id " \
" $suite " \
"main"
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
return 0
; ;
mongodb)
if [ [ -z " $repo_url " || -z " $gpg_key_url " ] ] ; then
msg_error "MongoDB repository requires repo_url and gpg_key_url"
return 1
fi
# Clean old repos first
cleanup_old_repo_files "mongodb"
# Import GPG key
mkdir -p /etc/apt/keyrings
if ! curl -fsSL " $gpg_key_url " | gpg --dearmor --yes -o " /etc/apt/keyrings/mongodb-server- ${ version } .gpg " 2>/dev/null; then
msg_error "Failed to download MongoDB GPG key"
return 1
fi
2026-02-12 22:24:24 +01:00
chmod 644 " /etc/apt/keyrings/mongodb-server- ${ version } .gpg "
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Setup repository
local distro_codename
distro_codename = $( awk -F= '/^VERSION_CODENAME=/{print $2}' /etc/os-release)
2025-11-06 07:57:30 +01:00
# Suite mapping with fallback for newer releases not yet supported by upstream
if [ [ " $distro_id " = = "debian" ] ] ; then
case " $distro_codename " in
trixie | forky | sid)
# Testing/unstable releases fallback to latest stable suite
suite = "bookworm"
; ;
bookworm)
suite = "bookworm"
; ;
bullseye)
suite = "bullseye"
; ;
*)
# Unknown release: fallback to latest stable suite
msg_warn " Unknown Debian release ' ${ distro_codename } ', using bookworm "
suite = "bookworm"
; ;
esac
elif [ [ " $distro_id " = = "ubuntu" ] ] ; then
case " $distro_codename " in
oracular | plucky)
# Newer releases fallback to latest LTS
suite = "noble"
; ;
noble)
suite = "noble"
; ;
jammy)
suite = "jammy"
; ;
focal)
suite = "focal"
; ;
*)
# Unknown release: fallback to latest LTS
msg_warn " Unknown Ubuntu release ' ${ distro_codename } ', using noble "
suite = "noble"
; ;
esac
else
# For other distros, try generic fallback
suite = $( get_fallback_suite " $distro_id " " $distro_codename " " $repo_url " )
fi
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
repo_component = "main"
[ [ " $distro_id " = = "ubuntu" ] ] && repo_component = "multiverse"
cat <<EOF >/etc/apt/sources.list.d/mongodb-org-${ version } .sources
Types: deb
URIs: ${ repo_url }
Suites: ${ suite } /mongodb-org/${ version }
Components: ${ repo_component }
2025-11-07 02:49:16 -08:00
Architectures: $( dpkg --print-architecture)
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
Signed-By: /etc/apt/keyrings/mongodb-server-${ version } .gpg
EOF
return 0
; ;
nodejs)
if [ [ -z " $repo_url " || -z " $gpg_key_url " ] ] ; then
msg_error "Node.js repository requires repo_url and gpg_key_url"
return 1
fi
cleanup_old_repo_files "nodesource"
# NodeSource uses deb822 format with GPG from repo
local distro_codename
distro_codename = $( awk -F= '/^VERSION_CODENAME=/{print $2}' /etc/os-release)
# Create keyring directory first
mkdir -p /etc/apt/keyrings
# Download GPG key from NodeSource
curl -fsSL " $gpg_key_url " | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg || {
msg_error "Failed to import NodeSource GPG key"
return 1
}
cat <<EOF >/etc/apt/sources.list.d/nodesource.sources
Types: deb
URIs: $repo_url
Suites: nodistro
Components: main
2025-11-07 02:49:16 -08:00
Architectures: $( dpkg --print-architecture)
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
Signed-By: /etc/apt/keyrings/nodesource.gpg
EOF
return 0
; ;
php)
if [ [ -z " $gpg_key_url " ] ] ; then
msg_error "PHP repository requires gpg_key_url"
return 1
fi
cleanup_old_repo_files "php"
# Download and install keyring
curl -fsSLo /tmp/debsuryorg-archive-keyring.deb " $gpg_key_url " || {
msg_error "Failed to download PHP keyring"
return 1
}
2026-01-28 11:09:30 +01:00
# Don't use /dev/null redirection for dpkg as it may use background processes
dpkg -i /tmp/debsuryorg-archive-keyring.deb >>" $( get_active_logfile) " 2>& 1 || {
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
msg_error "Failed to install PHP keyring"
rm -f /tmp/debsuryorg-archive-keyring.deb
return 1
}
rm -f /tmp/debsuryorg-archive-keyring.deb
# Setup repository
local distro_codename
distro_codename = $( awk -F= '/^VERSION_CODENAME=/{print $2}' /etc/os-release)
cat <<EOF >/etc/apt/sources.list.d/php.sources
Types: deb
URIs: https://packages.sury.org/php
Suites: $distro_codename
Components: main
2025-11-07 02:49:16 -08:00
Architectures: $( dpkg --print-architecture)
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
Signed-By: /usr/share/keyrings/deb.sury.org-php.gpg
EOF
return 0
; ;
postgresql)
if [ [ -z " $gpg_key_url " ] ] ; then
msg_error "PostgreSQL repository requires gpg_key_url"
return 1
fi
cleanup_old_repo_files "postgresql"
# Create keyring directory first
mkdir -p /etc/apt/keyrings
# Import PostgreSQL key
curl -fsSL " $gpg_key_url " | gpg --dearmor -o /etc/apt/keyrings/postgresql.gpg || {
msg_error "Failed to import PostgreSQL GPG key"
return 1
}
# Setup repository
local distro_codename
distro_codename = $( awk -F= '/^VERSION_CODENAME=/{print $2}' /etc/os-release)
cat <<EOF >/etc/apt/sources.list.d/postgresql.sources
Types: deb
URIs: http://apt.postgresql.org/pub/repos/apt
Suites: $distro_codename -pgdg
Components: main
2025-11-07 02:49:16 -08:00
Architectures: $( dpkg --print-architecture)
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
Signed-By: /etc/apt/keyrings/postgresql.gpg
EOF
return 0
; ;
*)
msg_error " Unknown tool repository: $tool_name "
return 1
; ;
esac
return 0
}
# ------– ----------------------------------------------------------------------
2025-10-22 06:25:26 -07:00
# Unified package upgrade function (with apt update caching)
# ------------------------------------------------------------------------------
upgrade_package( ) {
local package = " $1 "
# Use same caching logic as ensure_dependencies
local apt_cache_file = "/var/cache/apt-update-timestamp"
local current_time = $( date +%s)
local last_update = 0
if [ [ -f " $apt_cache_file " ] ] ; then
last_update = $( cat " $apt_cache_file " 2>/dev/null || echo 0)
fi
if ( ( current_time - last_update > 300) ) ; then
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
$STD apt update || {
msg_warn "APT update failed in upgrade_package - continuing with cached packages"
}
2025-10-22 06:25:26 -07:00
echo " $current_time " >" $apt_cache_file "
fi
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
$STD apt install --only-upgrade -y " $package " || {
msg_warn " Failed to upgrade $package "
return 1
}
2025-10-22 06:25:26 -07:00
}
# ------------------------------------------------------------------------------
# Repository availability check
# ------------------------------------------------------------------------------
verify_repo_available( ) {
local repo_url = " $1 "
local suite = " $2 "
if curl -fsSL --max-time 10 " ${ repo_url } /dists/ ${ suite } /Release " & >/dev/null; then
return 0
fi
return 1
}
# ------------------------------------------------------------------------------
# Ensure dependencies are installed (with apt update caching)
# ------------------------------------------------------------------------------
ensure_dependencies( ) {
local deps = ( " $@ " )
local missing = ( )
for dep in " ${ deps [@] } " ; do
if ! command -v " $dep " & >/dev/null && ! is_package_installed " $dep " ; then
missing += ( " $dep " )
fi
done
if [ [ ${# missing [@] } -gt 0 ] ] ; then
# Only run apt update if not done recently (within last 5 minutes)
local apt_cache_file = "/var/cache/apt-update-timestamp"
local current_time = $( date +%s)
local last_update = 0
if [ [ -f " $apt_cache_file " ] ] ; then
last_update = $( cat " $apt_cache_file " 2>/dev/null || echo 0)
fi
if ( ( current_time - last_update > 300) ) ; then
# Ensure orphaned sources are cleaned before updating
cleanup_orphaned_sources 2>/dev/null || true
if ! $STD apt update; then
ensure_apt_working || return 1
fi
echo " $current_time " >" $apt_cache_file "
fi
$STD apt install -y " ${ missing [@] } " || {
msg_error " Failed to install dependencies: ${ missing [*] } "
return 1
}
fi
}
# ------------------------------------------------------------------------------
# Smart version comparison
# ------------------------------------------------------------------------------
version_gt( ) {
test " $( printf '%s\n' " $@ " | sort -V | head -n 1) " != " $1 "
}
# ------------------------------------------------------------------------------
# Get system architecture (normalized)
# ------------------------------------------------------------------------------
get_system_arch( ) {
local arch_type = " ${ 1 :- dpkg } " # dpkg, uname, or both
local arch
case " $arch_type " in
dpkg)
arch = $( dpkg --print-architecture 2>/dev/null)
; ;
uname)
arch = $( uname -m)
[ [ " $arch " = = "x86_64" ] ] && arch = "amd64"
[ [ " $arch " = = "aarch64" ] ] && arch = "arm64"
; ;
both | *)
arch = $( dpkg --print-architecture 2>/dev/null || uname -m)
[ [ " $arch " = = "x86_64" ] ] && arch = "amd64"
[ [ " $arch " = = "aarch64" ] ] && arch = "arm64"
; ;
esac
echo " $arch "
}
# ------------------------------------------------------------------------------
# Create temporary directory with automatic cleanup
# ------------------------------------------------------------------------------
create_temp_dir( ) {
local tmp_dir = $( mktemp -d)
# Set trap to cleanup on EXIT, ERR, INT, TERM
trap " rm -rf ' $tmp_dir ' " EXIT ERR INT TERM
echo " $tmp_dir "
}
# ------------------------------------------------------------------------------
# Check if package is installed (faster than dpkg -l | grep)
# ------------------------------------------------------------------------------
is_package_installed( ) {
local package = " $1 "
dpkg-query -W -f= '${Status}' " $package " 2>/dev/null | grep -q " ^install ok installed $"
}
# ------------------------------------------------------------------------------
# GitHub API call with authentication and rate limit handling
# ------------------------------------------------------------------------------
github_api_call( ) {
local url = " $1 "
local output_file = " ${ 2 :- /dev/stdout } "
local max_retries = 3
local retry_delay = 2
local header_args = ( )
[ [ -n " ${ GITHUB_TOKEN :- } " ] ] && header_args = ( -H " Authorization: Bearer $GITHUB_TOKEN " )
for attempt in $( seq 1 $max_retries ) ; do
local http_code
2026-02-25 21:01:45 +01:00
http_code = $( curl -sSL -w "%{http_code}" -o " $output_file " \
2025-10-22 06:25:26 -07:00
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
" ${ header_args [@] } " \
2026-02-25 21:01:45 +01:00
" $url " 2>/dev/null) || true
2025-10-22 06:25:26 -07:00
case " $http_code " in
200)
return 0
; ;
2026-02-25 21:01:45 +01:00
401)
msg_error "GitHub API authentication failed (HTTP 401)."
if [ [ -n " ${ GITHUB_TOKEN :- } " ] ] ; then
msg_error "Your GITHUB_TOKEN appears to be invalid or expired."
else
msg_error "The repository may require authentication. Try: export GITHUB_TOKEN=\"ghp_your_token\""
fi
return 1
; ;
2025-10-22 06:25:26 -07:00
403)
# Rate limit - check if we can retry
if [ [ $attempt -lt $max_retries ] ] ; then
msg_warn " GitHub API rate limit, waiting ${ retry_delay } s... (attempt $attempt / $max_retries ) "
sleep " $retry_delay "
retry_delay = $(( retry_delay * 2 ))
continue
fi
2026-02-25 21:01:45 +01:00
msg_error "GitHub API rate limit exceeded (HTTP 403)."
msg_error "To increase the limit, export a GitHub token before running the script:"
msg_error " export GITHUB_TOKEN=\"ghp_your_token_here\""
2025-10-22 06:25:26 -07:00
return 1
; ;
404)
2026-02-25 21:01:45 +01:00
msg_error " GitHub repository or release not found (HTTP 404): $url "
return 1
; ;
000 | "" )
if [ [ $attempt -lt $max_retries ] ] ; then
sleep " $retry_delay "
continue
fi
msg_error "GitHub API connection failed (no response)."
msg_error "Check your network/DNS: curl -sSL https://api.github.com/rate_limit"
2025-10-22 06:25:26 -07:00
return 1
; ;
*)
if [ [ $attempt -lt $max_retries ] ] ; then
sleep " $retry_delay "
continue
fi
2026-02-25 21:01:45 +01:00
msg_error " GitHub API call failed (HTTP $http_code ). "
2025-10-22 06:25:26 -07:00
return 1
; ;
esac
done
return 1
}
2026-02-01 22:27:31 +01:00
# ------------------------------------------------------------------------------
# Codeberg API call with retry logic
# ------------------------------------------------------------------------------
codeberg_api_call( ) {
local url = " $1 "
local output_file = " ${ 2 :- /dev/stdout } "
local max_retries = 3
local retry_delay = 2
for attempt in $( seq 1 $max_retries ) ; do
local http_code
2026-02-25 21:01:45 +01:00
http_code = $( curl -sSL -w "%{http_code}" -o " $output_file " \
2026-02-01 22:27:31 +01:00
-H "Accept: application/json" \
2026-02-25 21:01:45 +01:00
" $url " 2>/dev/null) || true
2026-02-01 22:27:31 +01:00
case " $http_code " in
200)
return 0
; ;
2026-02-25 21:01:45 +01:00
401)
msg_error "Codeberg API authentication failed (HTTP 401)."
return 1
; ;
2026-02-01 22:27:31 +01:00
403)
# Rate limit - retry
if [ [ $attempt -lt $max_retries ] ] ; then
msg_warn " Codeberg API rate limit, waiting ${ retry_delay } s... (attempt $attempt / $max_retries ) "
sleep " $retry_delay "
retry_delay = $(( retry_delay * 2 ))
continue
fi
2026-02-25 21:01:45 +01:00
msg_error "Codeberg API rate limit exceeded (HTTP 403)."
2026-02-01 22:27:31 +01:00
return 1
; ;
404)
2026-02-25 21:01:45 +01:00
msg_error " Codeberg repository or release not found (HTTP 404): $url "
return 1
; ;
000 | "" )
if [ [ $attempt -lt $max_retries ] ] ; then
sleep " $retry_delay "
continue
fi
msg_error "Codeberg API connection failed (no response)."
msg_error "Check your network/DNS: curl -sSL https://codeberg.org"
2026-02-01 22:27:31 +01:00
return 1
; ;
*)
if [ [ $attempt -lt $max_retries ] ] ; then
sleep " $retry_delay "
continue
fi
2026-02-25 21:01:45 +01:00
msg_error " Codeberg API call failed (HTTP $http_code ). "
2026-02-01 22:27:31 +01:00
return 1
; ;
esac
done
return 1
}
2025-10-22 06:25:26 -07:00
should_upgrade( ) {
local current = " $1 "
local target = " $2 "
[ [ -z " $current " ] ] && return 0
version_gt " $target " " $current " && return 0
return 1
}
# ------------------------------------------------------------------------------
# Get OS information (cached for performance)
# ------------------------------------------------------------------------------
get_os_info( ) {
local field = " ${ 1 :- all } " # id, codename, version, version_id, all
# Cache OS info to avoid repeated file reads
if [ [ -z " ${ _OS_ID :- } " ] ] ; then
export _OS_ID = $( awk -F= '/^ID=/{gsub(/"/,"",$2); print $2}' /etc/os-release)
export _OS_CODENAME = $( awk -F= '/^VERSION_CODENAME=/{gsub(/"/,"",$2); print $2}' /etc/os-release)
export _OS_VERSION = $( awk -F= '/^VERSION_ID=/{gsub(/"/,"",$2); print $2}' /etc/os-release)
export _OS_VERSION_FULL = $( awk -F= '/^VERSION=/{gsub(/"/,"",$2); print $2}' /etc/os-release)
fi
case " $field " in
id) echo " $_OS_ID " ; ;
codename) echo " $_OS_CODENAME " ; ;
version) echo " $_OS_VERSION " ; ;
version_id) echo " $_OS_VERSION " ; ;
version_full) echo " $_OS_VERSION_FULL " ; ;
all) echo " ID= $_OS_ID CODENAME= $_OS_CODENAME VERSION= $_OS_VERSION " ; ;
*) echo " $_OS_ID " ; ;
esac
}
# ------------------------------------------------------------------------------
# Check if running on specific OS
# ------------------------------------------------------------------------------
is_debian( ) {
[ [ " $( get_os_info id) " = = "debian" ] ]
}
is_ubuntu( ) {
[ [ " $( get_os_info id) " = = "ubuntu" ] ]
}
is_alpine( ) {
[ [ " $( get_os_info id) " = = "alpine" ] ]
}
# ------------------------------------------------------------------------------
# Get Debian/Ubuntu major version
# ------------------------------------------------------------------------------
get_os_version_major( ) {
local version = $( get_os_info version)
echo " ${ version %%.* } "
}
# ------------------------------------------------------------------------------
# Download file with retry logic and progress
# ------------------------------------------------------------------------------
download_file( ) {
local url = " $1 "
local output = " $2 "
local max_retries = " ${ 3 :- 3 } "
local show_progress = " ${ 4 :- false } "
local curl_opts = ( -fsSL)
[ [ " $show_progress " = = "true" ] ] && curl_opts = ( -fL#)
for attempt in $( seq 1 $max_retries ) ; do
if curl " ${ curl_opts [@] } " -o " $output " " $url " ; then
return 0
fi
if [ [ $attempt -lt $max_retries ] ] ; then
msg_warn " Download failed, retrying... (attempt $attempt / $max_retries ) "
sleep 2
fi
done
msg_error " Failed to download: $url "
return 1
}
# ------------------------------------------------------------------------------
# Get fallback suite for repository (comprehensive mapping)
# ------------------------------------------------------------------------------
get_fallback_suite( ) {
local distro_id = " $1 "
local distro_codename = " $2 "
local repo_base_url = " $3 "
# Check if current codename works
if verify_repo_available " $repo_base_url " " $distro_codename " ; then
echo " $distro_codename "
return 0
fi
# Comprehensive fallback mappings
case " $distro_id " in
debian)
case " $distro_codename " in
# Debian 13 (Trixie) → Debian 12 (Bookworm)
trixie | forky | sid)
echo "bookworm"
; ;
# Debian 12 (Bookworm) stays
bookworm)
echo "bookworm"
; ;
# Debian 11 (Bullseye) stays
bullseye)
echo "bullseye"
; ;
# Unknown → latest stable
*)
echo "bookworm"
; ;
esac
; ;
ubuntu)
case " $distro_codename " in
# Ubuntu 24.10 (Oracular) → 24.04 LTS (Noble)
oracular | plucky)
echo "noble"
; ;
# Ubuntu 24.04 LTS (Noble) stays
noble)
echo "noble"
; ;
# Ubuntu 23.10 (Mantic) → 22.04 LTS (Jammy)
mantic | lunar)
echo "jammy"
; ;
# Ubuntu 22.04 LTS (Jammy) stays
jammy)
echo "jammy"
; ;
# Ubuntu 20.04 LTS (Focal) stays
focal)
echo "focal"
; ;
# Unknown → latest LTS
*)
echo "jammy"
; ;
esac
; ;
*)
echo " $distro_codename "
; ;
esac
}
# ------------------------------------------------------------------------------
# Verify package source and version
# ------------------------------------------------------------------------------
verify_package_source( ) {
local package = " $1 "
local expected_version = " $2 "
if apt-cache policy " $package " 2>/dev/null | grep -q " $expected_version " ; then
return 0
fi
return 1
}
# ------------------------------------------------------------------------------
# Check if running on LTS version
# ------------------------------------------------------------------------------
is_lts_version( ) {
local os_id = $( get_os_info id)
local codename = $( get_os_info codename)
if [ [ " $os_id " = = "ubuntu" ] ] ; then
case " $codename " in
focal | jammy | noble) return 0 ; ; # 20.04, 22.04, 24.04
*) return 1 ; ;
esac
elif [ [ " $os_id " = = "debian" ] ] ; then
# Debian releases are all "stable"
case " $codename " in
bullseye | bookworm | trixie) return 0 ; ;
*) return 1 ; ;
esac
fi
return 1
}
# ------------------------------------------------------------------------------
# Get optimal number of parallel jobs (cached)
# ------------------------------------------------------------------------------
get_parallel_jobs( ) {
if [ [ -z " ${ _PARALLEL_JOBS :- } " ] ] ; then
local cpu_count = $( nproc 2>/dev/null || echo 1)
local mem_gb = $( free -g | awk '/^Mem:/{print $2}' )
# Limit by available memory (assume 1GB per job for compilation)
local max_by_mem = $(( mem_gb > 0 ? mem_gb : 1 ))
local max_jobs = $(( cpu_count < max_by_mem ? cpu_count : max_by_mem))
# At least 1, at most cpu_count
export _PARALLEL_JOBS = $(( max_jobs > 0 ? max_jobs : 1 ))
fi
echo " $_PARALLEL_JOBS "
}
# ------------------------------------------------------------------------------
# Get default PHP version for OS
# ------------------------------------------------------------------------------
get_default_php_version( ) {
local os_id = $( get_os_info id)
local os_version = $( get_os_version_major)
case " $os_id " in
debian)
case " $os_version " in
13) echo "8.3" ; ; # Debian 13 (Trixie)
12) echo "8.2" ; ; # Debian 12 (Bookworm)
11) echo "7.4" ; ; # Debian 11 (Bullseye)
*) echo "8.2" ; ;
esac
; ;
ubuntu)
case " $os_version " in
24) echo "8.3" ; ; # Ubuntu 24.04 LTS (Noble)
22) echo "8.1" ; ; # Ubuntu 22.04 LTS (Jammy)
20) echo "7.4" ; ; # Ubuntu 20.04 LTS (Focal)
*) echo "8.1" ; ;
esac
; ;
*)
echo "8.2"
; ;
esac
}
# ------------------------------------------------------------------------------
# Get default Python version for OS
# ------------------------------------------------------------------------------
get_default_python_version( ) {
local os_id = $( get_os_info id)
local os_version = $( get_os_version_major)
case " $os_id " in
debian)
case " $os_version " in
13) echo "3.12" ; ; # Debian 13 (Trixie)
12) echo "3.11" ; ; # Debian 12 (Bookworm)
11) echo "3.9" ; ; # Debian 11 (Bullseye)
*) echo "3.11" ; ;
esac
; ;
ubuntu)
case " $os_version " in
24) echo "3.12" ; ; # Ubuntu 24.04 LTS
22) echo "3.10" ; ; # Ubuntu 22.04 LTS
20) echo "3.8" ; ; # Ubuntu 20.04 LTS
*) echo "3.10" ; ;
esac
; ;
*)
echo "3.11"
; ;
esac
}
# ------------------------------------------------------------------------------
# Get default Node.js LTS version
# ------------------------------------------------------------------------------
get_default_nodejs_version( ) {
# Always return current LTS (as of 2025)
2025-10-22 16:21:01 +02:00
echo "22"
2025-10-22 06:25:26 -07:00
}
# ------------------------------------------------------------------------------
# Check if package manager is locked
# ------------------------------------------------------------------------------
is_apt_locked( ) {
if fuser /var/lib/dpkg/lock-frontend & >/dev/null ||
fuser /var/lib/apt/lists/lock & >/dev/null ||
fuser /var/cache/apt/archives/lock & >/dev/null; then
return 0
fi
return 1
}
# ------------------------------------------------------------------------------
# Wait for apt to be available
# ------------------------------------------------------------------------------
wait_for_apt( ) {
local max_wait = " ${ 1 :- 300 } " # 5 minutes default
local waited = 0
while is_apt_locked; do
if [ [ $waited -ge $max_wait ] ] ; then
msg_error "Timeout waiting for apt to be available"
return 1
fi
sleep 5
waited = $(( waited + 5 ))
done
return 0
}
# ------------------------------------------------------------------------------
# Cleanup old repository files (migration helper)
# ------------------------------------------------------------------------------
cleanup_old_repo_files( ) {
local app = " $1 "
# Remove old-style .list files (including backups)
rm -f /etc/apt/sources.list.d/" ${ app } " *.list
rm -f /etc/apt/sources.list.d/" ${ app } " *.list.save
rm -f /etc/apt/sources.list.d/" ${ app } " *.list.distUpgrade
rm -f /etc/apt/sources.list.d/" ${ app } " *.list.dpkg-*
# Remove old GPG keys from trusted.gpg.d
rm -f /etc/apt/trusted.gpg.d/" ${ app } " *.gpg
# Remove keyrings from /etc/apt/keyrings
rm -f /etc/apt/keyrings/" ${ app } " *.gpg
# Remove ALL .sources files for this app (including the main one)
# This ensures no orphaned .sources files reference deleted keyrings
rm -f /etc/apt/sources.list.d/" ${ app } " *.sources
}
# ------------------------------------------------------------------------------
# Cleanup orphaned .sources files that reference missing keyrings
# This prevents APT signature verification errors
# Call this at the start of any setup function to ensure APT is in a clean state
# ------------------------------------------------------------------------------
cleanup_orphaned_sources( ) {
local sources_dir = "/etc/apt/sources.list.d"
local keyrings_dir = "/etc/apt/keyrings"
[ [ ! -d " $sources_dir " ] ] && return 0
while IFS = read -r -d '' sources_file; do
local basename_file
basename_file = $( basename " $sources_file " )
# NEVER remove debian.sources - this is the standard Debian repository
if [ [ " $basename_file " = = "debian.sources" ] ] ; then
continue
fi
# Extract Signed-By path from .sources file
local keyring_path
2025-12-18 18:38:08 +01:00
keyring_path = $( grep -E '^Signed-By:' " $sources_file " 2>/dev/null | awk '{print $2}' 2>/dev/null || true )
2025-10-22 06:25:26 -07:00
# If keyring doesn't exist, remove the .sources file
if [ [ -n " $keyring_path " ] ] && [ [ ! -f " $keyring_path " ] ] ; then
rm -f " $sources_file "
fi
done < <( find " $sources_dir " -name "*.sources" -print0 2>/dev/null)
# Also check for broken symlinks in keyrings directory
if [ [ -d " $keyrings_dir " ] ] ; then
find " $keyrings_dir " -type l ! -exec test -e { } \; -delete 2>/dev/null || true
fi
}
# ------------------------------------------------------------------------------
# Ensure APT is in a working state before installing packages
# This should be called at the start of any setup function
# ------------------------------------------------------------------------------
ensure_apt_working( ) {
2025-12-05 09:17:19 +01:00
# Fix interrupted dpkg operations first
# This can happen if a previous installation was interrupted (e.g., by script error)
if [ [ -f /var/lib/dpkg/lock-frontend ] ] || dpkg --audit 2>& 1 | grep -q "interrupted" ; then
$STD dpkg --configure -a 2>/dev/null || true
fi
2025-10-22 06:25:26 -07:00
# Clean up orphaned sources first
cleanup_orphaned_sources
# Try to update package lists
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
if ! $STD apt update; then
2025-10-22 06:25:26 -07:00
# More aggressive cleanup
rm -f /etc/apt/sources.list.d/*.sources 2>/dev/null || true
cleanup_orphaned_sources
# Try again
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
if ! $STD apt update; then
2025-10-22 06:25:26 -07:00
msg_error "Cannot update package lists - APT is critically broken"
return 1
fi
fi
return 0
}
# ------------------------------------------------------------------------------
2025-11-08 11:11:45 -08:00
# Standardized deb822 repository setup (with optional Architectures)
# Always runs apt update after repo creation to ensure package availability
2025-10-22 06:25:26 -07:00
# ------------------------------------------------------------------------------
setup_deb822_repo( ) {
local name = " $1 "
local gpg_url = " $2 "
local repo_url = " $3 "
local suite = " $4 "
Three-tier defaults system | security improvements | error_handler | improved logging | improved container creation | improved architecture (#9540)
* Refactor Core
Refactored misc/alpine-install.func to improve error handling, network checks, and MOTD setup. Added misc/alpine-tools.func and misc/error_handler.func for modular tool installation and error management. Enhanced misc/api.func with detailed exit code explanations and telemetry functions. Updated misc/core.func for better initialization, validation, and execution helpers. Removed misc/create_lxc.sh as part of cleanup.
* Delete config-file.func
* Update install.func
* Refactor stop_all_services function and variable names
Refactor service stopping logic and improve variable handling
* Refactor installation script and update copyright
Updated copyright information and adjusted package installation commands. Enhanced IPv6 disabling logic and improved container customization process.
* Update install.func
* Update license comment format in install.func
* Refactor IPv6 handling and enhance MOTD and SSH
Refactor IPv6 handling and update OS function. Enhance MOTD with additional details and configure SSH settings.
* big core refactor
* Enhance IPv6 configuration menu options
Updated IPv6 Address Management menu options for clarity and added a new option for fully disabling IPv6.
* Update default Node.js version to 24 LTS
* Update misc/alpine-tools.func
Co-authored-by: Michel Roegl-Brunner <73236783+michelroegl-brunner@users.noreply.github.com>
* indention
* remove debugf and duplicate codes
* Update whiptail backtitles and error codes
Removed '[dev]' from whiptail --backtitle strings for consistency. Refactored custom exit codes in build.func and error_handler.func: updated Proxmox error codes, shifted MySQL/MariaDB codes to 260-263, and removed unused MongoDB code. Updated error descriptions to match new codes.
* comments
* Refactor error handling and clean up debug comments
Standardized bash variable checks, removed unnecessary debug and commented code, and clarified error handling logic in container build and setup scripts. These changes improve code readability and maintainability without altering functional behavior.
* Update build.func
* feat: Improve LXC network checks and LINSTOR storage handling
Enhanced LXC container network setup to check for both IPv4 and IPv6 addresses, added connectivity (ping) tests, and provided troubleshooting tips on failure. Updated storage validation to support LINSTOR, including cluster connectivity checks and special handling for LINSTOR template storage.
---------
Co-authored-by: Michel Roegl-Brunner <73236783+michelroegl-brunner@users.noreply.github.com>
2025-12-04 07:52:18 +01:00
local component = " ${ 5 :- main } "
2025-11-10 13:58:04 +01:00
local architectures = " ${ 6 - } " # optional
2025-12-16 11:50:28 +01:00
local enabled = " ${ 7 - } " # optional: "true" or "false"
2025-10-22 06:25:26 -07:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Validate required parameters
if [ [ -z " $name " || -z " $gpg_url " || -z " $repo_url " || -z " $suite " ] ] ; then
2025-11-08 11:11:45 -08:00
msg_error " setup_deb822_repo: missing required parameters (name= $name repo= $repo_url suite= $suite ) "
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
return 1
fi
2025-11-08 11:11:45 -08:00
# Cleanup
2025-10-22 06:25:26 -07:00
cleanup_old_repo_files " $name "
cleanup_orphaned_sources
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
mkdir -p /etc/apt/keyrings || {
2025-11-08 11:11:45 -08:00
msg_error "Failed to create /etc/apt/keyrings"
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
return 1
}
2025-10-22 06:25:26 -07:00
2026-02-12 20:03:33 +01:00
# Import GPG key (auto-detect binary vs ASCII-armored format)
local tmp_gpg
tmp_gpg = $( mktemp) || return 1
curl -fsSL " $gpg_url " -o " $tmp_gpg " || {
msg_error " Failed to download GPG key for ${ name } "
rm -f " $tmp_gpg "
2025-10-22 06:25:26 -07:00
return 1
}
2026-02-12 22:30:34 +01:00
if grep -q "BEGIN PGP" " $tmp_gpg " 2>/dev/null; then
# ASCII-armored — dearmor to binary
2026-02-22 11:54:21 +01:00
gpg --dearmor --yes -o " /etc/apt/keyrings/ ${ name } .gpg " <" $tmp_gpg " || {
2026-02-12 22:30:34 +01:00
msg_error " Failed to dearmor GPG key for ${ name } "
2026-02-12 20:03:33 +01:00
rm -f " $tmp_gpg "
return 1
}
else
2026-02-12 22:30:34 +01:00
# Already in binary GPG format — copy directly
cp " $tmp_gpg " " /etc/apt/keyrings/ ${ name } .gpg " || {
msg_error " Failed to install GPG key for ${ name } "
2026-02-12 20:03:33 +01:00
rm -f " $tmp_gpg "
return 1
}
fi
rm -f " $tmp_gpg "
2026-02-12 22:24:24 +01:00
chmod 644 " /etc/apt/keyrings/ ${ name } .gpg "
2026-02-12 20:03:33 +01:00
2025-11-08 11:11:45 -08:00
# Write deb822
{
echo "Types: deb"
echo " URIs: $repo_url "
echo " Suites: $suite "
2025-12-15 17:29:48 +01:00
# Flat repositories (suite="./" or absolute path) must not have Components
if [ [ " $suite " != "./" && -n " $component " ] ] ; then
echo " Components: $component "
fi
2025-11-08 11:11:45 -08:00
[ [ -n " $architectures " ] ] && echo " Architectures: $architectures "
echo " Signed-By: /etc/apt/keyrings/ ${ name } .gpg "
2025-12-16 11:50:28 +01:00
[ [ -n " $enabled " ] ] && echo " Enabled: $enabled "
2025-11-08 11:11:45 -08:00
} >/etc/apt/sources.list.d/${ name } .sources
$STD apt update
2025-10-22 06:25:26 -07:00
}
# ------------------------------------------------------------------------------
# Package version hold/unhold helpers
# ------------------------------------------------------------------------------
hold_package_version( ) {
local package = " $1 "
$STD apt-mark hold " $package "
}
unhold_package_version( ) {
local package = " $1 "
$STD apt-mark unhold " $package "
}
# ------------------------------------------------------------------------------
# Safe service restart with verification
# ------------------------------------------------------------------------------
safe_service_restart( ) {
local service = " $1 "
if systemctl is-active --quiet " $service " ; then
$STD systemctl restart " $service "
else
$STD systemctl start " $service "
fi
if ! systemctl is-active --quiet " $service " ; then
msg_error " Failed to start $service "
systemctl status " $service " --no-pager
return 1
fi
return 0
}
# ------------------------------------------------------------------------------
# Enable and start service (with error handling)
# ------------------------------------------------------------------------------
enable_and_start_service( ) {
local service = " $1 "
if ! systemctl enable " $service " & >/dev/null; then
return 1
fi
if ! systemctl start " $service " & >/dev/null; then
msg_error " Failed to start $service "
systemctl status " $service " --no-pager
return 1
fi
return 0
}
# ------------------------------------------------------------------------------
# Check if service is enabled
# ------------------------------------------------------------------------------
is_service_enabled( ) {
local service = " $1 "
systemctl is-enabled --quiet " $service " 2>/dev/null
}
# ------------------------------------------------------------------------------
# Check if service is running
# ------------------------------------------------------------------------------
is_service_running( ) {
local service = " $1 "
systemctl is-active --quiet " $service " 2>/dev/null
}
# ------------------------------------------------------------------------------
# Extract version from JSON (GitHub releases)
# ------------------------------------------------------------------------------
extract_version_from_json( ) {
local json = " $1 "
local field = " ${ 2 :- tag_name } "
local strip_v = " ${ 3 :- true } "
ensure_dependencies jq
local version
version = $( echo " $json " | jq -r " . ${ field } // empty " )
if [ [ -z " $version " ] ] ; then
return 1
fi
if [ [ " $strip_v " = = "true" ] ] ; then
echo " ${ version #v } "
else
echo " $version "
fi
}
# ------------------------------------------------------------------------------
# Get latest GitHub release version
# ------------------------------------------------------------------------------
get_latest_github_release( ) {
local repo = " $1 "
local strip_v = " ${ 2 :- true } "
local temp_file = $( mktemp)
if ! github_api_call " https://api.github.com/repos/ ${ repo } /releases/latest " " $temp_file " ; then
rm -f " $temp_file "
2026-02-25 21:01:45 +01:00
return 0
2025-10-22 06:25:26 -07:00
fi
local version
version = $( extract_version_from_json " $( cat " $temp_file " ) " "tag_name" " $strip_v " )
rm -f " $temp_file "
if [ [ -z " $version " ] ] ; then
2026-02-25 21:01:45 +01:00
msg_error " Could not determine latest version for ${ repo } "
return 0
2025-10-22 06:25:26 -07:00
fi
echo " $version "
}
2026-02-01 22:27:31 +01:00
# ------------------------------------------------------------------------------
# Get latest Codeberg release version
# ------------------------------------------------------------------------------
get_latest_codeberg_release( ) {
local repo = " $1 "
local strip_v = " ${ 2 :- true } "
local temp_file = $( mktemp)
# Codeberg API: get all releases and pick the first non-draft/non-prerelease
if ! codeberg_api_call " https://codeberg.org/api/v1/repos/ ${ repo } /releases " " $temp_file " ; then
rm -f " $temp_file "
2026-02-25 21:01:45 +01:00
return 0
2026-02-01 22:27:31 +01:00
fi
local version
# Codeberg uses same JSON structure but releases endpoint returns array
version = $( jq -r '[.[] | select(.draft==false and .prerelease==false)][0].tag_name // empty' " $temp_file " )
if [ [ " $strip_v " = = "true" ] ] ; then
version = " ${ version #v } "
fi
rm -f " $temp_file "
if [ [ -z " $version " ] ] ; then
2026-02-25 21:01:45 +01:00
msg_error " Could not determine latest version for ${ repo } "
return 0
2026-02-01 22:27:31 +01:00
fi
echo " $version "
}
2025-10-22 06:25:26 -07:00
# ------------------------------------------------------------------------------
# Debug logging (only if DEBUG=1)
# ------------------------------------------------------------------------------
debug_log( ) {
[ [ " ${ DEBUG :- 0 } " = = "1" ] ] && echo " [DEBUG] $* " >& 2
}
# ------------------------------------------------------------------------------
# Performance timing helper
# ------------------------------------------------------------------------------
start_timer( ) {
echo $( date +%s)
}
end_timer( ) {
local start_time = " $1 "
local label = " ${ 2 :- Operation } "
local end_time = $( date +%s)
local duration = $(( end_time - start_time))
}
# ------------------------------------------------------------------------------
# GPG key fingerprint verification
# ------------------------------------------------------------------------------
verify_gpg_fingerprint( ) {
local key_file = " $1 "
local expected_fingerprint = " $2 "
local actual_fingerprint
actual_fingerprint = $( gpg --show-keys --with-fingerprint --with-colons " $key_file " 2>& 1 | grep -m1 '^fpr:' | cut -d: -f10)
if [ [ " $actual_fingerprint " = = " $expected_fingerprint " ] ] ; then
return 0
fi
msg_error " GPG fingerprint mismatch! Expected: $expected_fingerprint , Got: $actual_fingerprint "
return 1
}
2026-02-24 11:07:40 +01:00
# ------------------------------------------------------------------------------
# Get latest GitHub tag for a repository.
#
# Description:
# - Queries the GitHub API for tags (not releases)
# - Useful for repos that only create tags, not full releases
# - Supports optional prefix filter and version-only extraction
# - Returns the latest tag name (printed to stdout)
#
# Usage:
# MONGO_VERSION=$(get_latest_gh_tag "mongodb/mongo-tools")
# LATEST=$(get_latest_gh_tag "owner/repo" "v") # only tags starting with "v"
# LATEST=$(get_latest_gh_tag "owner/repo" "" "true") # strip leading "v"
#
# Arguments:
# $1 - GitHub repo (owner/repo)
# $2 - Tag prefix filter (optional, e.g. "v" or "100.")
# $3 - Strip prefix from result (optional, "true" to strip $2 prefix)
#
# Returns:
# 0 on success (tag printed to stdout), 1 on failure
#
# Notes:
# - Skips tags containing "rc", "alpha", "beta", "dev", "test"
# - Sorts by version number (sort -V) to find the latest
# - Respects GITHUB_TOKEN for rate limiting
# ------------------------------------------------------------------------------
get_latest_gh_tag( ) {
local repo = " $1 "
local prefix = " ${ 2 :- } "
local strip_prefix = " ${ 3 :- false } "
local header_args = ( )
[ [ -n " ${ GITHUB_TOKEN :- } " ] ] && header_args = ( -H " Authorization: Bearer $GITHUB_TOKEN " )
local http_code = ""
http_code = $( curl -sSL --max-time 20 -w "%{http_code}" -o /tmp/gh_tags.json \
-H 'Accept: application/vnd.github+json' \
-H 'X-GitHub-Api-Version: 2022-11-28' \
" ${ header_args [@] } " \
" https://api.github.com/repos/ ${ repo } /tags?per_page=100 " 2>/dev/null) || true
2026-02-25 21:01:45 +01:00
if [ [ " $http_code " = = "401" ] ] ; then
msg_error "GitHub API authentication failed (HTTP 401)."
if [ [ -n " ${ GITHUB_TOKEN :- } " ] ] ; then
msg_error "Your GITHUB_TOKEN appears to be invalid or expired."
else
msg_error "The repository may require authentication. Try: export GITHUB_TOKEN=\"ghp_your_token\""
fi
rm -f /tmp/gh_tags.json
return 1
fi
2026-02-24 11:07:40 +01:00
if [ [ " $http_code " = = "403" ] ] ; then
2026-02-25 21:01:45 +01:00
msg_error "GitHub API rate limit exceeded (HTTP 403)."
msg_error "To increase the limit, export a GitHub token before running the script:"
msg_error " export GITHUB_TOKEN=\"ghp_your_token_here\""
rm -f /tmp/gh_tags.json
return 1
fi
if [ [ " $http_code " = = "000" || -z " $http_code " ] ] ; then
msg_error "GitHub API connection failed (no response)."
msg_error "Check your network/DNS: curl -sSL https://api.github.com/rate_limit"
2026-02-24 11:07:40 +01:00
rm -f /tmp/gh_tags.json
return 1
fi
if [ [ " $http_code " != "200" ] ] || [ [ ! -s /tmp/gh_tags.json ] ] ; then
2026-02-25 21:01:45 +01:00
msg_error " Unable to fetch tags for ${ repo } (HTTP ${ http_code } ) "
2026-02-24 11:07:40 +01:00
rm -f /tmp/gh_tags.json
return 1
fi
local tags_json
tags_json = $( </tmp/gh_tags.json)
rm -f /tmp/gh_tags.json
# Extract tag names, filter by prefix, exclude pre-release patterns, sort by version
local latest = ""
latest = $( echo " $tags_json " | grep -oP '"name":\s*"\K[^"]+' |
{ [ [ -n " $prefix " ] ] && grep " ^ ${ prefix } " || cat; } |
grep -viE '(rc|alpha|beta|dev|test|preview|snapshot)' |
sort -V | tail -n1)
if [ [ -z " $latest " ] ] ; then
return 1
fi
if [ [ " $strip_prefix " = = "true" && -n " $prefix " ] ] ; then
latest = " ${ latest # " $prefix " } "
fi
echo " $latest "
return 0
}
2025-10-22 06:25:26 -07:00
# ==============================================================================
2025-11-10 13:22:59 +01:00
# INSTALL FUNCTIONS
2025-10-22 06:25:26 -07:00
# ==============================================================================
2025-05-15 15:18:41 +02:00
# ------------------------------------------------------------------------------
2025-09-11 12:44:13 +02:00
# Checks for new GitHub release (latest tag).
2025-05-15 15:18:41 +02:00
#
# Description:
2025-09-11 12:44:13 +02:00
# - Queries the GitHub API for the latest release tag
# - Compares it to a local cached version (~/.<app>)
# - If newer, sets global CHECK_UPDATE_RELEASE and returns 0
2025-05-15 15:18:41 +02:00
#
2025-09-11 12:44:13 +02:00
# Usage:
# if check_for_gh_release "flaresolverr" "FlareSolverr/FlareSolverr" [optional] "v1.1.1"; then
# # trigger update...
# fi
# exit 0
# } (end of update_script not from the function)
#
# Notes:
# - Requires `jq` (auto-installed if missing)
# - Does not modify anything, only checks version state
# - Does not support pre-releases
2025-05-15 15:18:41 +02:00
# ------------------------------------------------------------------------------
2025-09-11 12:44:13 +02:00
check_for_gh_release( ) {
local app = " $1 "
local source = " $2 "
local pinned_version_in = " ${ 3 :- } " # optional
2026-02-03 16:08:34 -05:00
local app_lc = ""
app_lc = " $( echo " ${ app ,, } " | tr -d ' ' ) "
2025-09-11 12:44:13 +02:00
local current_file = " $HOME /. ${ app_lc } "
2025-05-15 15:18:41 +02:00
2025-09-11 12:44:13 +02:00
msg_info " Checking for update: ${ app } "
2025-05-05 15:47:43 +02:00
2025-09-11 12:44:13 +02:00
# DNS check
if ! getent hosts api.github.com >/dev/null 2>& 1; then
msg_error "Network error: cannot resolve api.github.com"
return 1
2025-05-05 15:47:43 +02:00
fi
2025-04-28 15:25:10 +02:00
2025-10-22 06:25:26 -07:00
ensure_dependencies jq
2025-05-27 13:48:34 +02:00
2026-02-22 11:54:21 +01:00
# Build auth header if token is available
local header_args = ( )
[ [ -n " ${ GITHUB_TOKEN :- } " ] ] && header_args = ( -H " Authorization: Bearer $GITHUB_TOKEN " )
2025-12-09 06:49:43 -08:00
# Try /latest endpoint for non-pinned versions (most efficient)
2026-02-22 11:54:21 +01:00
local releases_json = "" http_code = ""
use setup_hwaccel for robust hardware acceleration (#10054)
* fix(jellyfin): use setup_hwaccel for robust hardware acceleration
Replaces manual hardware acceleration setup with the centralized
setup_hwaccel function from tools.func.
This fixes the installation failure in privileged containers where
/dev/dri does not exist (e.g., when no GPU is passed through).
The setup_hwaccel function includes:
- Proper error handling for missing /dev/dri
- GPU vendor detection (Intel, AMD, NVIDIA)
- Graceful fallback when no GPU is available
Fixes: Installation fails with 'chgrp: cannot access /dev/dri'
when creating privileged containers without GPU passthrough.
* refactor(hwaccel): standardize hardware acceleration across all install scripts
Migrated all install scripts to use the centralized setup_hwaccel function:
- plex-install.sh
- emby-install.sh
- ersatztv-install.sh
- frigate-install.sh
- tdarr-install.sh
- unmanic-install.sh
- channels-install.sh
- ollama-install.sh
- immich-install.sh (added error handling)
Enhanced setup_hwaccel function in tools.func:
- Added -d /dev/dri check before setting permissions
- Added error handling (2>/dev/null || true) for all /dev/dri operations
- Added adduser error handling for video/render groups
- No longer fails if no GPU is detected (graceful skip)
- Added intel-media-va-driver for newer Intel GPUs
- Improved AMD APU support with firmware packages
- Better NVIDIA handling (warning instead of failure)
This fixes installation failures in privileged containers without GPU
passthrough, where /dev/dri does not exist.
Supports: Ubuntu, Debian 12 (Bookworm), Debian 13 (Trixie)
GPU Support: Intel, AMD, NVIDIA (manual driver)
* refactor(hwaccel): complete migration for all GPU apps
Migrated remaining GPU apps to setup_hwaccel:
- fileflows-install.sh
- openwebui-install.sh (added setup_hwaccel - was missing)
- tunarr-install.sh
Also fixed tools/pve/hw-acceleration.sh:
- Added error handling for /dev/dri operations
- Added chmod 660 /dev/dri/* that was missing
- Added error suppression for adduser commands
All 13 GPU apps (var_gpu=yes) now use centralized setup_hwaccel:
jellyfin, plex, emby, ersatztv, frigate, tdarr, unmanic,
channels, ollama, immich, fileflows, openwebui, tunarr
* feat(hwaccel): complete Intel non-free driver support and GID sync
Enhanced setup_hwaccel function:
- Auto-detect Intel GPU generation (Gen 9+ for non-free drivers)
- Debian 12 (Bookworm): Add non-free repo + intel-media-va-driver-non-free
- Debian 13 (Trixie): Add non-free repo + libvpl2 + mesa-opencl-icd
- Ubuntu: Use ubuntu repos with intel-media-va-driver
- Fallback to open drivers if non-free fails
- GID sync for video/render groups (moved from install scripts)
OpenWebUI: Added Intel oneAPI support when installing Ollama
- Intel Level Zero GPU support
- Intel oneAPI Base Toolkit
- Same setup as standalone Ollama install
Cleanup:
- Removed duplicate GID sync from tdarr-install.sh
- Removed duplicate GID sync from unmanic-install.sh
* fix(ersatztv): remove duplicate HW acceleration code
Removed manual Intel HW acceleration setup that remained after
setup_hwaccel migration. The non-free driver prompt is no longer
needed as setup_hwaccel auto-detects Intel GPU generation.
2025-12-17 14:37:31 +01:00
2025-12-09 06:49:43 -08:00
if [ [ -z " $pinned_version_in " ] ] ; then
2026-02-22 11:54:21 +01:00
http_code = $( curl -sSL --max-time 20 -w "%{http_code}" -o /tmp/gh_check.json \
2025-12-09 06:49:43 -08:00
-H 'Accept: application/vnd.github+json' \
-H 'X-GitHub-Api-Version: 2022-11-28' \
2026-02-22 11:54:21 +01:00
" ${ header_args [@] } " \
" https://api.github.com/repos/ ${ source } /releases/latest " 2>/dev/null) || true
if [ [ " $http_code " = = "200" ] ] && [ [ -s /tmp/gh_check.json ] ] ; then
releases_json = " [ $( </tmp/gh_check.json) ] "
2026-02-25 21:01:45 +01:00
elif [ [ " $http_code " = = "401" ] ] ; then
msg_error "GitHub API authentication failed (HTTP 401)."
if [ [ -n " ${ GITHUB_TOKEN :- } " ] ] ; then
msg_error "Your GITHUB_TOKEN appears to be invalid or expired."
else
msg_error "The repository may require authentication. Try: export GITHUB_TOKEN=\"ghp_your_token\""
fi
rm -f /tmp/gh_check.json
return 1
2026-02-22 11:54:21 +01:00
elif [ [ " $http_code " = = "403" ] ] ; then
msg_error "GitHub API rate limit exceeded (HTTP 403)."
msg_error "To increase the limit, export a GitHub token before running the script:"
msg_error " export GITHUB_TOKEN=\"ghp_your_token_here\""
rm -f /tmp/gh_check.json
return 1
2025-12-09 06:49:43 -08:00
fi
2026-02-22 11:54:21 +01:00
rm -f /tmp/gh_check.json
2025-12-09 06:49:43 -08:00
fi
use setup_hwaccel for robust hardware acceleration (#10054)
* fix(jellyfin): use setup_hwaccel for robust hardware acceleration
Replaces manual hardware acceleration setup with the centralized
setup_hwaccel function from tools.func.
This fixes the installation failure in privileged containers where
/dev/dri does not exist (e.g., when no GPU is passed through).
The setup_hwaccel function includes:
- Proper error handling for missing /dev/dri
- GPU vendor detection (Intel, AMD, NVIDIA)
- Graceful fallback when no GPU is available
Fixes: Installation fails with 'chgrp: cannot access /dev/dri'
when creating privileged containers without GPU passthrough.
* refactor(hwaccel): standardize hardware acceleration across all install scripts
Migrated all install scripts to use the centralized setup_hwaccel function:
- plex-install.sh
- emby-install.sh
- ersatztv-install.sh
- frigate-install.sh
- tdarr-install.sh
- unmanic-install.sh
- channels-install.sh
- ollama-install.sh
- immich-install.sh (added error handling)
Enhanced setup_hwaccel function in tools.func:
- Added -d /dev/dri check before setting permissions
- Added error handling (2>/dev/null || true) for all /dev/dri operations
- Added adduser error handling for video/render groups
- No longer fails if no GPU is detected (graceful skip)
- Added intel-media-va-driver for newer Intel GPUs
- Improved AMD APU support with firmware packages
- Better NVIDIA handling (warning instead of failure)
This fixes installation failures in privileged containers without GPU
passthrough, where /dev/dri does not exist.
Supports: Ubuntu, Debian 12 (Bookworm), Debian 13 (Trixie)
GPU Support: Intel, AMD, NVIDIA (manual driver)
* refactor(hwaccel): complete migration for all GPU apps
Migrated remaining GPU apps to setup_hwaccel:
- fileflows-install.sh
- openwebui-install.sh (added setup_hwaccel - was missing)
- tunarr-install.sh
Also fixed tools/pve/hw-acceleration.sh:
- Added error handling for /dev/dri operations
- Added chmod 660 /dev/dri/* that was missing
- Added error suppression for adduser commands
All 13 GPU apps (var_gpu=yes) now use centralized setup_hwaccel:
jellyfin, plex, emby, ersatztv, frigate, tdarr, unmanic,
channels, ollama, immich, fileflows, openwebui, tunarr
* feat(hwaccel): complete Intel non-free driver support and GID sync
Enhanced setup_hwaccel function:
- Auto-detect Intel GPU generation (Gen 9+ for non-free drivers)
- Debian 12 (Bookworm): Add non-free repo + intel-media-va-driver-non-free
- Debian 13 (Trixie): Add non-free repo + libvpl2 + mesa-opencl-icd
- Ubuntu: Use ubuntu repos with intel-media-va-driver
- Fallback to open drivers if non-free fails
- GID sync for video/render groups (moved from install scripts)
OpenWebUI: Added Intel oneAPI support when installing Ollama
- Intel Level Zero GPU support
- Intel oneAPI Base Toolkit
- Same setup as standalone Ollama install
Cleanup:
- Removed duplicate GID sync from tdarr-install.sh
- Removed duplicate GID sync from unmanic-install.sh
* fix(ersatztv): remove duplicate HW acceleration code
Removed manual Intel HW acceleration setup that remained after
setup_hwaccel migration. The non-free driver prompt is no longer
needed as setup_hwaccel auto-detects Intel GPU generation.
2025-12-17 14:37:31 +01:00
2025-12-09 06:49:43 -08:00
# If no releases yet (pinned version OR /latest failed), fetch up to 100
if [ [ -z " $releases_json " ] ] ; then
2026-02-22 11:54:21 +01:00
http_code = $( curl -sSL --max-time 20 -w "%{http_code}" -o /tmp/gh_check.json \
2025-12-09 06:49:43 -08:00
-H 'Accept: application/vnd.github+json' \
-H 'X-GitHub-Api-Version: 2022-11-28' \
2026-02-22 11:54:21 +01:00
" ${ header_args [@] } " \
" https://api.github.com/repos/ ${ source } /releases?per_page=100 " 2>/dev/null) || true
if [ [ " $http_code " = = "200" ] ] && [ [ -s /tmp/gh_check.json ] ] ; then
releases_json = $( </tmp/gh_check.json)
2026-02-25 21:01:45 +01:00
elif [ [ " $http_code " = = "401" ] ] ; then
msg_error "GitHub API authentication failed (HTTP 401)."
if [ [ -n " ${ GITHUB_TOKEN :- } " ] ] ; then
msg_error "Your GITHUB_TOKEN appears to be invalid or expired."
else
msg_error "The repository may require authentication. Try: export GITHUB_TOKEN=\"ghp_your_token\""
fi
rm -f /tmp/gh_check.json
return 1
2026-02-22 11:54:21 +01:00
elif [ [ " $http_code " = = "403" ] ] ; then
msg_error "GitHub API rate limit exceeded (HTTP 403)."
msg_error "To increase the limit, export a GitHub token before running the script:"
msg_error " export GITHUB_TOKEN=\"ghp_your_token_here\""
rm -f /tmp/gh_check.json
2025-12-09 06:49:43 -08:00
return 1
2026-02-25 21:01:45 +01:00
elif [ [ " $http_code " = = "000" || -z " $http_code " ] ] ; then
msg_error "GitHub API connection failed (no response)."
msg_error "Check your network/DNS: curl -sSL https://api.github.com/rate_limit"
rm -f /tmp/gh_check.json
return 1
2026-02-22 11:54:21 +01:00
else
msg_error " Unable to fetch releases for ${ app } (HTTP ${ http_code } ) "
rm -f /tmp/gh_check.json
return 1
fi
rm -f /tmp/gh_check.json
2025-12-09 06:49:43 -08:00
fi
2025-04-28 15:25:10 +02:00
2025-09-11 12:44:13 +02:00
mapfile -t raw_tags < <( jq -r '.[] | select(.draft==false and .prerelease==false) | .tag_name' <<< " $releases_json " )
if ( ( ${# raw_tags [@] } = = 0) ) ; then
msg_error " No stable releases found for ${ app } "
return 1
fi
2025-04-28 15:25:10 +02:00
2025-09-11 12:44:13 +02:00
local clean_tags = ( )
for t in " ${ raw_tags [@] } " ; do
clean_tags += ( " ${ t #v } " )
done
2025-04-28 15:25:10 +02:00
2025-09-11 12:44:13 +02:00
local latest_raw = " ${ raw_tags [0] } "
local latest_clean = " ${ clean_tags [0] } "
2025-05-05 15:47:43 +02:00
2025-09-11 12:44:13 +02:00
# current installed (stored without v)
local current = ""
if [ [ -f " $current_file " ] ] ; then
current = " $( <" $current_file " ) "
else
# Migration: search for any /opt/*_version.txt
local legacy_files
mapfile -t legacy_files < <( find /opt -maxdepth 1 -type f -name "*_version.txt" 2>/dev/null)
if ( ( ${# legacy_files [@] } = = 1) ) ; then
current = " $( <" ${ legacy_files [0] } " ) "
echo " ${ current #v } " >" $current_file "
rm -f " ${ legacy_files [0] } "
fi
fi
current = " ${ current #v } "
# Pinned version handling
if [ [ -n " $pinned_version_in " ] ] ; then
local pin_clean = " ${ pinned_version_in #v } "
local match_raw = ""
for i in " ${ !clean_tags[@] } " ; do
if [ [ " ${ clean_tags [ $i ] } " = = " $pin_clean " ] ] ; then
match_raw = " ${ raw_tags [ $i ] } "
break
2025-07-10 13:58:20 +02:00
fi
2025-09-11 12:44:13 +02:00
done
if [ [ -z " $match_raw " ] ] ; then
msg_error " Pinned version ${ pinned_version_in } not found upstream "
return 1
2025-07-10 13:58:20 +02:00
fi
2025-09-11 12:44:13 +02:00
if [ [ " $current " != " $pin_clean " ] ] ; then
CHECK_UPDATE_RELEASE = " $match_raw "
2025-10-23 04:06:13 -07:00
msg_ok " Update available: ${ app } ${ current :- not installed } → ${ pin_clean } "
2025-09-11 12:44:13 +02:00
return 0
2025-04-28 15:25:10 +02:00
fi
2025-11-10 13:22:59 +01:00
msg_ok " No update available: ${ app } is already on pinned version ( ${ current } ) "
2025-09-11 12:44:13 +02:00
return 1
2025-05-05 15:47:43 +02:00
fi
2025-04-28 15:25:10 +02:00
2025-09-11 12:44:13 +02:00
# No pinning → use latest
if [ [ -z " $current " || " $current " != " $latest_clean " ] ] ; then
CHECK_UPDATE_RELEASE = " $latest_raw "
2025-10-23 04:06:13 -07:00
msg_ok " Update available: ${ app } ${ current :- not installed } → ${ latest_clean } "
2025-09-11 12:44:13 +02:00
return 0
2025-06-26 18:24:43 +02:00
fi
2025-05-05 15:47:43 +02:00
2025-10-23 04:06:13 -07:00
msg_ok " No update available: ${ app } ( ${ latest_clean } ) "
2025-09-11 12:44:13 +02:00
return 1
2025-05-05 15:47:43 +02:00
}
2025-04-28 15:25:10 +02:00
2026-02-01 22:27:31 +01:00
# ------------------------------------------------------------------------------
# Checks for new Codeberg release (latest tag).
#
# Description:
# - Queries the Codeberg API for the latest release tag
# - Compares it to a local cached version (~/.<app>)
# - If newer, sets global CHECK_UPDATE_RELEASE and returns 0
#
# Usage:
# if check_for_codeberg_release "autocaliweb" "gelbphoenix/autocaliweb" [optional] "v0.11.3"; then
# # trigger update...
# fi
# exit 0
# } (end of update_script not from the function)
#
# Notes:
# - Requires `jq` (auto-installed if missing)
# - Does not modify anything, only checks version state
# - Does not support pre-releases
# ------------------------------------------------------------------------------
check_for_codeberg_release( ) {
local app = " $1 "
local source = " $2 "
local pinned_version_in = " ${ 3 :- } " # optional
local app_lc = " ${ app ,, } "
local current_file = " $HOME /. ${ app_lc } "
msg_info " Checking for update: ${ app } "
# DNS check
if ! getent hosts codeberg.org >/dev/null 2>& 1; then
msg_error "Network error: cannot resolve codeberg.org"
return 1
fi
ensure_dependencies jq
# Fetch releases from Codeberg API
local releases_json = ""
releases_json = $( curl -fsSL --max-time 20 \
-H 'Accept: application/json' \
" https://codeberg.org/api/v1/repos/ ${ source } /releases " 2>/dev/null) || {
msg_error " Unable to fetch releases for ${ app } "
return 1
}
mapfile -t raw_tags < <( jq -r '.[] | select(.draft==false and .prerelease==false) | .tag_name' <<< " $releases_json " )
if ( ( ${# raw_tags [@] } = = 0) ) ; then
msg_error " No stable releases found for ${ app } "
return 1
fi
local clean_tags = ( )
for t in " ${ raw_tags [@] } " ; do
clean_tags += ( " ${ t #v } " )
done
local latest_raw = " ${ raw_tags [0] } "
local latest_clean = " ${ clean_tags [0] } "
# current installed (stored without v)
local current = ""
if [ [ -f " $current_file " ] ] ; then
current = " $( <" $current_file " ) "
else
# Migration: search for any /opt/*_version.txt
local legacy_files
mapfile -t legacy_files < <( find /opt -maxdepth 1 -type f -name "*_version.txt" 2>/dev/null)
if ( ( ${# legacy_files [@] } = = 1) ) ; then
current = " $( <" ${ legacy_files [0] } " ) "
echo " ${ current #v } " >" $current_file "
rm -f " ${ legacy_files [0] } "
fi
fi
current = " ${ current #v } "
# Pinned version handling
if [ [ -n " $pinned_version_in " ] ] ; then
local pin_clean = " ${ pinned_version_in #v } "
local match_raw = ""
for i in " ${ !clean_tags[@] } " ; do
if [ [ " ${ clean_tags [ $i ] } " = = " $pin_clean " ] ] ; then
match_raw = " ${ raw_tags [ $i ] } "
break
fi
done
if [ [ -z " $match_raw " ] ] ; then
msg_error " Pinned version ${ pinned_version_in } not found upstream "
return 1
fi
if [ [ " $current " != " $pin_clean " ] ] ; then
CHECK_UPDATE_RELEASE = " $match_raw "
msg_ok " Update available: ${ app } ${ current :- not installed } → ${ pin_clean } "
return 0
fi
msg_ok " No update available: ${ app } is already on pinned version ( ${ current } ) "
return 1
fi
# No pinning → use latest
if [ [ -z " $current " || " $current " != " $latest_clean " ] ] ; then
CHECK_UPDATE_RELEASE = " $latest_raw "
msg_ok " Update available: ${ app } ${ current :- not installed } → ${ latest_clean } "
return 0
fi
msg_ok " No update available: ${ app } ( ${ latest_clean } ) "
return 1
}
2025-05-15 15:18:41 +02:00
# ------------------------------------------------------------------------------
2025-09-11 12:44:13 +02:00
# Creates and installs self-signed certificates.
2025-05-15 15:18:41 +02:00
#
# Description:
2025-09-11 12:44:13 +02:00
# - Create a self-signed certificate with option to override application name
2025-05-15 15:18:41 +02:00
#
# Variables:
2025-09-11 12:44:13 +02:00
# APP - Application name (default: $APPLICATION variable)
2025-05-15 15:18:41 +02:00
# ------------------------------------------------------------------------------
2025-10-22 06:25:26 -07:00
create_self_signed_cert( ) {
local APP_NAME = " ${ 1 :- ${ APPLICATION } } "
2025-12-01 20:35:12 +01:00
local APP_NAME_LC = $( echo " ${ APP_NAME ,, } " | tr -d ' ' )
local CERT_DIR = " /etc/ssl/ ${ APP_NAME_LC } "
local CERT_KEY = " ${ CERT_DIR } / ${ APP_NAME_LC } .key "
local CERT_CRT = " ${ CERT_DIR } / ${ APP_NAME_LC } .crt "
2025-10-22 06:25:26 -07:00
if [ [ -f " $CERT_CRT " && -f " $CERT_KEY " ] ] ; then
return 0
fi
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Use ensure_dependencies for cleaner handling
ensure_dependencies openssl || {
2025-10-22 06:25:26 -07:00
msg_error "Failed to install OpenSSL"
return 1
}
mkdir -p " $CERT_DIR "
$STD openssl req -new -newkey rsa:2048 -days 365 -nodes -x509 \
2025-11-30 17:34:14 +01:00
-subj " /CN= ${ APP_NAME } " \
-addext " subjectAltName=DNS: ${ APP_NAME } " \
2025-10-22 06:25:26 -07:00
-keyout " $CERT_KEY " \
-out " $CERT_CRT " || {
msg_error "Failed to create self-signed certificate"
return 1
}
chmod 600 " $CERT_KEY "
chmod 644 " $CERT_CRT "
2025-09-11 12:44:13 +02:00
}
2025-05-05 15:47:43 +02:00
2025-09-11 12:44:13 +02:00
# ------------------------------------------------------------------------------
# Downloads file with optional progress indicator using pv.
#
# Arguments:
# $1 - URL
# $2 - Destination path
# ------------------------------------------------------------------------------
2025-08-28 14:43:56 +02:00
2025-09-11 12:44:13 +02:00
function download_with_progress( ) {
local url = " $1 "
local output = " $2 "
if [ -n " $SPINNER_PID " ] && ps -p " $SPINNER_PID " >/dev/null; then kill " $SPINNER_PID " >/dev/null; fi
2025-10-22 06:25:26 -07:00
ensure_dependencies pv
2025-09-11 12:44:13 +02:00
set -o pipefail
2025-05-05 15:47:43 +02:00
2025-09-11 12:44:13 +02:00
# Content-Length aus HTTP-Header holen
local content_length
content_length = $( curl -fsSLI " $url " | awk '/Content-Length/ {print $2}' | tr -d '\r' || true )
2025-05-05 15:47:43 +02:00
2025-09-11 12:44:13 +02:00
if [ [ -z " $content_length " ] ] ; then
if ! curl -fL# -o " $output " " $url " ; then
msg_error "Download failed"
return 1
2025-05-15 15:18:41 +02:00
fi
2025-09-11 12:44:13 +02:00
else
if ! curl -fsSL " $url " | pv -s " $content_length " >" $output " ; then
msg_error "Download failed"
return 1
2025-05-13 10:38:19 +02:00
fi
2025-09-11 12:44:13 +02:00
fi
}
2025-05-13 10:38:19 +02:00
2025-09-11 12:44:13 +02:00
# ------------------------------------------------------------------------------
# Ensures /usr/local/bin is permanently in system PATH.
#
# Description:
2026-02-16 10:30:05 +01:00
# - Adds to /etc/profile.d for login shells (SSH, noVNC)
# - Adds to /root/.bashrc for non-login shells (pct enter)
2025-09-11 12:44:13 +02:00
# ------------------------------------------------------------------------------
2025-05-13 10:38:19 +02:00
2025-09-11 12:44:13 +02:00
function ensure_usr_local_bin_persist( ) {
2026-02-16 10:30:05 +01:00
# Skip on Proxmox host
command -v pveversion & >/dev/null && return
2025-05-27 14:29:50 +02:00
2026-02-16 10:30:05 +01:00
# Login shells: /etc/profile.d/
local PROFILE_FILE = "/etc/profile.d/custom_path.sh"
if [ [ ! -f " $PROFILE_FILE " ] ] ; then
2025-09-11 12:44:13 +02:00
echo 'export PATH="/usr/local/bin:$PATH"' >" $PROFILE_FILE "
chmod +x " $PROFILE_FILE "
2025-05-27 14:29:50 +02:00
fi
2026-02-16 10:30:05 +01:00
# Non-login shells (pct enter): /root/.bashrc
local BASHRC = "/root/.bashrc"
if [ [ -f " $BASHRC " ] ] && ! grep -q '/usr/local/bin' " $BASHRC " ; then
echo 'export PATH="/usr/local/bin:$PATH"' >>" $BASHRC "
fi
2025-04-28 15:25:10 +02:00
}
2026-02-01 22:27:31 +01:00
# ------------------------------------------------------------------------------
# Downloads and deploys latest Codeberg release (source, binary, tarball, asset).
#
# Description:
# - Fetches latest release metadata from Codeberg API
# - Supports the following modes:
# - tarball: Source code tarball (default if omitted)
# - source: Alias for tarball (same behavior)
# - binary: .deb package install (arch-dependent)
# - prebuild: Prebuilt .tar.gz archive (e.g. Go binaries)
# - singlefile: Standalone binary (no archive, direct chmod +x install)
# - tag: Direct tag download (bypasses Release API)
# - Handles download, extraction/installation and version tracking in ~/.<app>
#
# Parameters:
# $1 APP - Application name (used for install path and version file)
# $2 REPO - Codeberg repository in form user/repo
# $3 MODE - Release type:
# tarball → source tarball (.tar.gz)
# binary → .deb file (auto-arch matched)
# prebuild → prebuilt archive (e.g. tar.gz)
# singlefile→ standalone binary (chmod +x)
# tag → direct tag (bypasses Release API)
# $4 VERSION - Optional release tag (default: latest)
# $5 TARGET_DIR - Optional install path (default: /opt/<app>)
# $6 ASSET_FILENAME - Required for:
# - prebuild → archive filename or pattern
# - singlefile→ binary filename or pattern
#
# Examples:
# # 1. Minimal: Fetch and deploy source tarball
# fetch_and_deploy_codeberg_release "autocaliweb" "gelbphoenix/autocaliweb"
#
# # 2. Binary install via .deb asset (architecture auto-detected)
# fetch_and_deploy_codeberg_release "myapp" "myuser/myapp" "binary"
#
# # 3. Prebuilt archive (.tar.gz) with asset filename match
# fetch_and_deploy_codeberg_release "myapp" "myuser/myapp" "prebuild" "latest" "/opt/myapp" "myapp_Linux_x86_64.tar.gz"
#
# # 4. Single binary (chmod +x)
# fetch_and_deploy_codeberg_release "myapp" "myuser/myapp" "singlefile" "v1.0.0" "/opt/myapp" "myapp-linux-amd64"
#
# # 5. Explicit tag version
# fetch_and_deploy_codeberg_release "autocaliweb" "gelbphoenix/autocaliweb" "tag" "v0.11.3" "/opt/autocaliweb"
# ------------------------------------------------------------------------------
function fetch_and_deploy_codeberg_release( ) {
local app = " $1 "
local repo = " $2 "
local mode = " ${ 3 :- tarball } " # tarball | binary | prebuild | singlefile | tag
2026-02-14 16:37:13 +01:00
local version = " ${ var_appversion :- ${ 4 :- latest } } "
2026-02-01 22:27:31 +01:00
local target = " ${ 5 :- /opt/ $app } "
local asset_pattern = " ${ 6 :- } "
local app_lc = $( echo " ${ app ,, } " | tr -d ' ' )
local version_file = " $HOME /. ${ app_lc } "
local api_timeout = "--connect-timeout 10 --max-time 60"
local download_timeout = "--connect-timeout 15 --max-time 900"
local current_version = ""
[ [ -f " $version_file " ] ] && current_version = $( <" $version_file " )
ensure_dependencies jq
### Tag Mode (bypass Release API) ###
if [ [ " $mode " = = "tag" ] ] ; then
if [ [ " $version " = = "latest" ] ] ; then
msg_error "Mode 'tag' requires explicit version (not 'latest')"
return 1
fi
local tag_name = " $version "
[ [ " $tag_name " = ~ ^v ] ] && version = " ${ tag_name : 1 } " || version = " $tag_name "
if [ [ " $current_version " = = " $version " ] ] ; then
$STD msg_ok " $app is already up-to-date (v $version ) "
return 0
fi
# DNS check
if ! getent hosts "codeberg.org" & >/dev/null; then
msg_error "DNS resolution failed for codeberg.org – check /etc/resolv.conf or networking"
return 1
fi
local tmpdir
tmpdir = $( mktemp -d) || return 1
msg_info " Fetching Codeberg tag: $app ( $tag_name ) "
local safe_version = " ${ version //@/_ } "
safe_version = " ${ safe_version // \/ /_ } "
local filename = " ${ app_lc } - ${ safe_version } .tar.gz "
local download_success = false
# Codeberg archive URL format: https://codeberg.org/{owner}/{repo}/archive/{tag}.tar.gz
local archive_url = " https://codeberg.org/ $repo /archive/ ${ tag_name } .tar.gz "
if curl $download_timeout -fsSL -o " $tmpdir / $filename " " $archive_url " ; then
download_success = true
fi
if [ [ " $download_success " != "true" ] ] ; then
msg_error " Download failed for $app ( $tag_name ) "
rm -rf " $tmpdir "
return 1
fi
mkdir -p " $target "
if [ [ " ${ CLEAN_INSTALL :- 0 } " = = "1" ] ] ; then
rm -rf " ${ target : ? } / " *
fi
tar --no-same-owner -xzf " $tmpdir / $filename " -C " $tmpdir " || {
msg_error "Failed to extract tarball"
rm -rf " $tmpdir "
return 1
}
local unpack_dir
unpack_dir = $( find " $tmpdir " -mindepth 1 -maxdepth 1 -type d | head -n1)
shopt -s dotglob nullglob
cp -r " $unpack_dir " /* " $target / "
shopt -u dotglob nullglob
echo " $version " >" $version_file "
msg_ok " Deployed: $app ( $version ) "
rm -rf " $tmpdir "
return 0
fi
# Codeberg API: https://codeberg.org/api/v1/repos/{owner}/{repo}/releases
local api_url = " https://codeberg.org/api/v1/repos/ $repo /releases "
if [ [ " $version " != "latest" ] ] ; then
# Get release by tag: /repos/{owner}/{repo}/releases/tags/{tag}
api_url = " https://codeberg.org/api/v1/repos/ $repo /releases/tags/ $version "
fi
# dns pre check
if ! getent hosts "codeberg.org" & >/dev/null; then
msg_error "DNS resolution failed for codeberg.org – check /etc/resolv.conf or networking"
return 1
fi
local max_retries = 3 retry_delay = 2 attempt = 1 success = false resp http_code
while ( ( attempt <= max_retries) ) ; do
resp = $( curl $api_timeout -fsSL -w "%{http_code}" -o /tmp/codeberg_rel.json " $api_url " ) && success = true && break
sleep " $retry_delay "
( ( attempt++) )
done
if ! $success ; then
msg_error " Failed to fetch release metadata from $api_url after $max_retries attempts "
return 1
fi
http_code = " ${ resp : (-3) } "
[ [ " $http_code " != "200" ] ] && {
msg_error " Codeberg API returned HTTP $http_code "
return 1
}
local json tag_name
json = $( </tmp/codeberg_rel.json)
# For "latest", the API returns an array - take the first (most recent) release
if [ [ " $version " = = "latest" ] ] ; then
json = $( echo " $json " | jq '.[0]' )
fi
tag_name = $( echo " $json " | jq -r '.tag_name // .name // empty' )
[ [ " $tag_name " = ~ ^v ] ] && version = " ${ tag_name : 1 } " || version = " $tag_name "
if [ [ " $current_version " = = " $version " ] ] ; then
$STD msg_ok " $app is already up-to-date (v $version ) "
return 0
fi
local tmpdir
tmpdir = $( mktemp -d) || return 1
local filename = "" url = ""
msg_info " Fetching Codeberg release: $app ( $version ) "
### Tarball Mode ###
if [ [ " $mode " = = "tarball" || " $mode " = = "source" ] ] ; then
local safe_version = " ${ version //@/_ } "
safe_version = " ${ safe_version // \/ /_ } "
filename = " ${ app_lc } - ${ safe_version } .tar.gz "
local download_success = false
# Codeberg archive URL format
local archive_url = " https://codeberg.org/ $repo /archive/ ${ tag_name } .tar.gz "
if curl $download_timeout -fsSL -o " $tmpdir / $filename " " $archive_url " ; then
download_success = true
fi
if [ [ " $download_success " != "true" ] ] ; then
msg_error " Download failed for $app ( $tag_name ) "
rm -rf " $tmpdir "
return 1
fi
mkdir -p " $target "
if [ [ " ${ CLEAN_INSTALL :- 0 } " = = "1" ] ] ; then
rm -rf " ${ target : ? } / " *
fi
tar --no-same-owner -xzf " $tmpdir / $filename " -C " $tmpdir " || {
msg_error "Failed to extract tarball"
rm -rf " $tmpdir "
return 1
}
local unpack_dir
unpack_dir = $( find " $tmpdir " -mindepth 1 -maxdepth 1 -type d | head -n1)
shopt -s dotglob nullglob
cp -r " $unpack_dir " /* " $target / "
shopt -u dotglob nullglob
### Binary Mode ###
elif [ [ " $mode " = = "binary" ] ] ; then
local arch
arch = $( dpkg --print-architecture 2>/dev/null || uname -m)
[ [ " $arch " = = "x86_64" ] ] && arch = "amd64"
[ [ " $arch " = = "aarch64" ] ] && arch = "arm64"
local assets url_match = ""
# Codeberg assets are in .assets[].browser_download_url
assets = $( echo " $json " | jq -r '.assets[].browser_download_url' )
# If explicit filename pattern is provided, match that first
if [ [ -n " $asset_pattern " ] ] ; then
for u in $assets ; do
case " ${ u ##*/ } " in
$asset_pattern )
url_match = " $u "
break
; ;
esac
done
fi
# Fall back to architecture heuristic
if [ [ -z " $url_match " ] ] ; then
for u in $assets ; do
if [ [ " $u " = ~ ( $arch | amd64| x86_64| aarch64| arm64) .*\. deb$ ] ] ; then
url_match = " $u "
break
fi
done
fi
# Fallback: any .deb file
if [ [ -z " $url_match " ] ] ; then
for u in $assets ; do
[ [ " $u " = ~ \. deb$ ] ] && url_match = " $u " && break
done
fi
if [ [ -z " $url_match " ] ] ; then
msg_error " No suitable .deb asset found for $app "
rm -rf " $tmpdir "
return 1
fi
filename = " ${ url_match ##*/ } "
curl $download_timeout -fsSL -o " $tmpdir / $filename " " $url_match " || {
msg_error " Download failed: $url_match "
rm -rf " $tmpdir "
return 1
}
chmod 644 " $tmpdir / $filename "
$STD apt install -y " $tmpdir / $filename " || {
$STD dpkg -i " $tmpdir / $filename " || {
msg_error "Both apt and dpkg installation failed"
rm -rf " $tmpdir "
return 1
}
}
### Prebuild Mode ###
elif [ [ " $mode " = = "prebuild" ] ] ; then
local pattern = " ${ 6 % \" } "
pattern = " ${ pattern # \" } "
[ [ -z " $pattern " ] ] && {
msg_error "Mode 'prebuild' requires 6th parameter (asset filename pattern)"
rm -rf " $tmpdir "
return 1
}
local asset_url = ""
for u in $( echo " $json " | jq -r '.assets[].browser_download_url' ) ; do
filename_candidate = " ${ u ##*/ } "
case " $filename_candidate " in
$pattern )
asset_url = " $u "
break
; ;
esac
done
[ [ -z " $asset_url " ] ] && {
msg_error " No asset matching ' $pattern ' found "
rm -rf " $tmpdir "
return 1
}
filename = " ${ asset_url ##*/ } "
curl $download_timeout -fsSL -o " $tmpdir / $filename " " $asset_url " || {
msg_error " Download failed: $asset_url "
rm -rf " $tmpdir "
return 1
}
local unpack_tmp
unpack_tmp = $( mktemp -d)
mkdir -p " $target "
if [ [ " ${ CLEAN_INSTALL :- 0 } " = = "1" ] ] ; then
rm -rf " ${ target : ? } / " *
fi
if [ [ " $filename " = = *.zip ] ] ; then
ensure_dependencies unzip
unzip -q " $tmpdir / $filename " -d " $unpack_tmp " || {
msg_error "Failed to extract ZIP archive"
rm -rf " $tmpdir " " $unpack_tmp "
return 1
}
elif [ [ " $filename " = = *.tar.* || " $filename " = = *.tgz ] ] ; then
tar --no-same-owner -xf " $tmpdir / $filename " -C " $unpack_tmp " || {
msg_error "Failed to extract TAR archive"
rm -rf " $tmpdir " " $unpack_tmp "
return 1
}
else
msg_error " Unsupported archive format: $filename "
rm -rf " $tmpdir " " $unpack_tmp "
return 1
fi
local top_dirs
top_dirs = $( find " $unpack_tmp " -mindepth 1 -maxdepth 1 -type d | wc -l)
local top_entries inner_dir
top_entries = $( find " $unpack_tmp " -mindepth 1 -maxdepth 1)
if [ [ " $( echo " $top_entries " | wc -l) " -eq 1 && -d " $top_entries " ] ] ; then
inner_dir = " $top_entries "
shopt -s dotglob nullglob
if compgen -G " $inner_dir /* " >/dev/null; then
cp -r " $inner_dir " /* " $target / " || {
msg_error " Failed to copy contents from $inner_dir to $target "
rm -rf " $tmpdir " " $unpack_tmp "
return 1
}
else
msg_error " Inner directory is empty: $inner_dir "
rm -rf " $tmpdir " " $unpack_tmp "
return 1
fi
shopt -u dotglob nullglob
else
shopt -s dotglob nullglob
if compgen -G " $unpack_tmp /* " >/dev/null; then
cp -r " $unpack_tmp " /* " $target / " || {
msg_error " Failed to copy contents to $target "
rm -rf " $tmpdir " " $unpack_tmp "
return 1
}
else
msg_error "Unpacked archive is empty"
rm -rf " $tmpdir " " $unpack_tmp "
return 1
fi
shopt -u dotglob nullglob
fi
### Singlefile Mode ###
elif [ [ " $mode " = = "singlefile" ] ] ; then
local pattern = " ${ 6 % \" } "
pattern = " ${ pattern # \" } "
[ [ -z " $pattern " ] ] && {
msg_error "Mode 'singlefile' requires 6th parameter (asset filename pattern)"
rm -rf " $tmpdir "
return 1
}
local asset_url = ""
for u in $( echo " $json " | jq -r '.assets[].browser_download_url' ) ; do
filename_candidate = " ${ u ##*/ } "
case " $filename_candidate " in
$pattern )
asset_url = " $u "
break
; ;
esac
done
[ [ -z " $asset_url " ] ] && {
msg_error " No asset matching ' $pattern ' found "
rm -rf " $tmpdir "
return 1
}
filename = " ${ asset_url ##*/ } "
mkdir -p " $target "
local use_filename = " ${ USE_ORIGINAL_FILENAME :- false } "
local target_file = " $app "
[ [ " $use_filename " = = "true" ] ] && target_file = " $filename "
curl $download_timeout -fsSL -o " $target / $target_file " " $asset_url " || {
msg_error " Download failed: $asset_url "
rm -rf " $tmpdir "
return 1
}
if [ [ " $target_file " != *.jar && -f " $target / $target_file " ] ] ; then
chmod +x " $target / $target_file "
fi
else
msg_error " Unknown mode: $mode "
rm -rf " $tmpdir "
return 1
fi
echo " $version " >" $version_file "
msg_ok " Deployed: $app ( $version ) "
rm -rf " $tmpdir "
}
2025-05-15 15:18:41 +02:00
# ------------------------------------------------------------------------------
2025-09-11 12:44:13 +02:00
# Downloads and deploys latest GitHub release (source, binary, tarball, asset).
2025-05-15 15:18:41 +02:00
#
# Description:
2025-09-11 12:44:13 +02:00
# - Fetches latest release metadata from GitHub API
# - Supports the following modes:
# - tarball: Source code tarball (default if omitted)
# - source: Alias for tarball (same behavior)
# - binary: .deb package install (arch-dependent)
# - prebuild: Prebuilt .tar.gz archive (e.g. Go binaries)
# - singlefile: Standalone binary (no archive, direct chmod +x install)
# - Handles download, extraction/installation and version tracking in ~/.<app>
2025-05-15 15:18:41 +02:00
#
2025-09-11 12:44:13 +02:00
# Parameters:
# $1 APP - Application name (used for install path and version file)
# $2 REPO - GitHub repository in form user/repo
# $3 MODE - Release type:
# tarball → source tarball (.tar.gz)
# binary → .deb file (auto-arch matched)
# prebuild → prebuilt archive (e.g. tar.gz)
# singlefile→ standalone binary (chmod +x)
# $4 VERSION - Optional release tag (default: latest)
# $5 TARGET_DIR - Optional install path (default: /opt/<app>)
# $6 ASSET_FILENAME - Required for:
# - prebuild → archive filename or pattern
# - singlefile→ binary filename or pattern
#
# Optional:
# - Set GITHUB_TOKEN env var to increase API rate limit (recommended for CI/CD).
#
# Examples:
# # 1. Minimal: Fetch and deploy source tarball
# fetch_and_deploy_gh_release "myapp" "myuser/myapp"
#
# # 2. Binary install via .deb asset (architecture auto-detected)
# fetch_and_deploy_gh_release "myapp" "myuser/myapp" "binary"
#
# # 3. Prebuilt archive (.tar.gz) with asset filename match
# fetch_and_deploy_gh_release "hanko" "teamhanko/hanko" "prebuild" "latest" "/opt/hanko" "hanko_Linux_x86_64.tar.gz"
#
# # 4. Single binary (chmod +x) like Argus, Promtail etc.
# fetch_and_deploy_gh_release "argus" "release-argus/Argus" "singlefile" "0.26.3" "/opt/argus" "Argus-.*linux-amd64"
2026-02-07 20:37:50 +01:00
#
# Notes:
# - For binary/prebuild/singlefile modes: if the target release has no
# matching asset, the function scans older releases and prompts the user
# (60s timeout, default yes) to use a previous version that has the asset.
# ------------------------------------------------------------------------------
2025-05-15 15:18:41 +02:00
# ------------------------------------------------------------------------------
2026-02-07 20:37:50 +01:00
# Scans older GitHub releases for a matching asset when the latest release
# is missing the expected file. Used internally by fetch_and_deploy_gh_release.
#
# Arguments:
# $1 - GitHub repo (owner/repo)
# $2 - mode (binary|prebuild|singlefile)
# $3 - asset_pattern (glob pattern for asset filename)
# $4 - tag to skip (the already-checked release)
#
# Output:
# Prints the release JSON of the first older release that has a matching asset.
# Returns 0 on success, 1 if no matching release found or user declined.
# ------------------------------------------------------------------------------
_gh_scan_older_releases( ) {
local repo = " $1 "
local mode = " $2 "
local asset_pattern = " $3 "
local skip_tag = " $4 "
local header = ( )
[ [ -n " ${ GITHUB_TOKEN :- } " ] ] && header = ( -H " Authorization: token $GITHUB_TOKEN " )
local releases_list
releases_list = $( curl --connect-timeout 10 --max-time 30 -fsSL \
-H 'Accept: application/vnd.github+json' \
-H 'X-GitHub-Api-Version: 2022-11-28' \
" ${ header [@] } " \
" https://api.github.com/repos/ ${ repo } /releases?per_page=15 " 2>/dev/null) || return 1
local count
count = $( echo " $releases_list " | jq 'length' )
for ( ( i = 0; i < count; i++) ) ; do
local rel_tag rel_draft rel_prerelease
rel_tag = $( echo " $releases_list " | jq -r " .[ $i ].tag_name " )
rel_draft = $( echo " $releases_list " | jq -r " .[ $i ].draft " )
rel_prerelease = $( echo " $releases_list " | jq -r " .[ $i ].prerelease " )
# Skip drafts, prereleases, and the tag we already checked
[ [ " $rel_draft " = = "true" || " $rel_prerelease " = = "true" ] ] && continue
[ [ " $rel_tag " = = " $skip_tag " ] ] && continue
local has_match = false
if [ [ " $mode " = = "binary" ] ] ; then
local arch
arch = $( dpkg --print-architecture 2>/dev/null || uname -m)
[ [ " $arch " = = "x86_64" ] ] && arch = "amd64"
[ [ " $arch " = = "aarch64" ] ] && arch = "arm64"
# Check with explicit pattern first, then arch heuristic, then any .deb
if [ [ -n " $asset_pattern " ] ] ; then
has_match = $( echo " $releases_list " | jq -r --arg pat " $asset_pattern " " .[ $i ].assets[].name " | while read -r name; do
2026-02-22 11:54:21 +01:00
case " $name " in $asset_pattern )
echo true
break
; ;
esac
2026-02-07 20:37:50 +01:00
done )
fi
if [ [ " $has_match " != "true" ] ] ; then
has_match = $( echo " $releases_list " | jq -r " .[ $i ].assets[].browser_download_url " | grep -qE " ( $arch |amd64|x86_64|aarch64|arm64).*\.deb $" && echo true )
fi
if [ [ " $has_match " != "true" ] ] ; then
has_match = $( echo " $releases_list " | jq -r " .[ $i ].assets[].browser_download_url " | grep -qE '\.deb$' && echo true )
fi
elif [ [ " $mode " = = "prebuild" || " $mode " = = "singlefile" ] ] ; then
has_match = $( echo " $releases_list " | jq -r " .[ $i ].assets[].name " | while read -r name; do
2026-02-22 11:54:21 +01:00
case " $name " in $asset_pattern )
echo true
break
; ;
esac
2026-02-07 20:37:50 +01:00
done )
fi
if [ [ " $has_match " = = "true" ] ] ; then
local rel_version = " $rel_tag "
[ [ " $rel_tag " = ~ ^v ] ] && rel_version = " ${ rel_tag : 1 } "
local use_fallback = "y"
if [ [ -t 0 ] ] ; then
msg_warn " Release ${ skip_tag } has no matching asset. Previous release ${ rel_tag } has a compatible asset. "
read -rp " Use version ${ rel_tag } instead? [Y/n] (auto-yes in 60s): " -t 60 use_fallback || use_fallback = "y"
use_fallback = " ${ use_fallback :- y } "
fi
if [ [ " ${ use_fallback ,, } " = = "y" || " ${ use_fallback ,, } " = = "yes" ] ] ; then
echo " $releases_list " | jq " .[ $i ] "
return 0
else
return 1
fi
fi
done
return 1
}
2025-05-15 15:18:41 +02:00
2025-09-11 12:44:13 +02:00
function fetch_and_deploy_gh_release( ) {
local app = " $1 "
local repo = " $2 "
local mode = " ${ 3 :- tarball } " # tarball | binary | prebuild | singlefile
2026-02-14 16:37:13 +01:00
local version = " ${ var_appversion :- ${ 4 :- latest } } "
2025-09-11 12:44:13 +02:00
local target = " ${ 5 :- /opt/ $app } "
local asset_pattern = " ${ 6 :- } "
2025-05-05 15:47:43 +02:00
2025-09-11 12:44:13 +02:00
local app_lc = $( echo " ${ app ,, } " | tr -d ' ' )
local version_file = " $HOME /. ${ app_lc } "
2025-07-04 21:22:50 +02:00
2025-09-11 12:44:13 +02:00
local api_timeout = "--connect-timeout 10 --max-time 60"
local download_timeout = "--connect-timeout 15 --max-time 900"
2025-05-05 15:47:43 +02:00
2025-09-11 12:44:13 +02:00
local current_version = ""
[ [ -f " $version_file " ] ] && current_version = $( <" $version_file " )
2025-05-05 15:47:43 +02:00
2025-10-22 06:25:26 -07:00
ensure_dependencies jq
2025-05-05 15:47:43 +02:00
2025-09-11 12:44:13 +02:00
local api_url = " https://api.github.com/repos/ $repo /releases "
[ [ " $version " != "latest" ] ] && api_url = " $api_url /tags/ $version " || api_url = " $api_url /latest "
local header = ( )
[ [ -n " ${ GITHUB_TOKEN :- } " ] ] && header = ( -H " Authorization: token $GITHUB_TOKEN " )
2025-05-05 15:47:43 +02:00
2025-09-11 12:44:13 +02:00
# dns pre check
local gh_host
gh_host = $( awk -F/ '{print $3}' <<< " $api_url " )
if ! getent hosts " $gh_host " & >/dev/null; then
msg_error " DNS resolution failed for $gh_host – check /etc/resolv.conf or networking "
return 1
fi
2025-05-05 15:47:43 +02:00
2026-02-22 11:54:21 +01:00
local max_retries = 3 retry_delay = 2 attempt = 1 success = false http_code
2025-05-05 15:47:43 +02:00
2025-09-11 12:44:13 +02:00
while ( ( attempt <= max_retries) ) ; do
2026-02-22 11:54:21 +01:00
http_code = $( curl $api_timeout -sSL -w "%{http_code}" -o /tmp/gh_rel.json " ${ header [@] } " " $api_url " 2>/dev/null) || true
if [ [ " $http_code " = = "200" ] ] ; then
success = true
break
elif [ [ " $http_code " = = "403" ] ] ; then
if ( ( attempt < max_retries) ) ; then
msg_warn " GitHub API rate limit hit, retrying in ${ retry_delay } s... (attempt $attempt / $max_retries ) "
sleep " $retry_delay "
retry_delay = $(( retry_delay * 2 ))
fi
else
sleep " $retry_delay "
fi
2025-09-11 12:44:13 +02:00
( ( attempt++) )
done
2025-08-08 10:28:05 +02:00
2025-09-11 12:44:13 +02:00
if ! $success ; then
2026-02-25 21:01:45 +01:00
if [ [ " $http_code " = = "401" ] ] ; then
msg_error "GitHub API authentication failed (HTTP 401)."
if [ [ -n " ${ GITHUB_TOKEN :- } " ] ] ; then
msg_error "Your GITHUB_TOKEN appears to be invalid or expired."
else
msg_error "The repository may require authentication. Try: export GITHUB_TOKEN=\"ghp_your_token\""
fi
elif [ [ " $http_code " = = "403" ] ] ; then
2026-02-22 11:54:21 +01:00
msg_error "GitHub API rate limit exceeded (HTTP 403)."
msg_error "To increase the limit, export a GitHub token before running the script:"
msg_error " export GITHUB_TOKEN=\"ghp_your_token_here\""
2026-02-25 21:01:45 +01:00
elif [ [ " $http_code " = = "000" || -z " $http_code " ] ] ; then
msg_error "GitHub API connection failed (no response)."
msg_error "Check your network/DNS: curl -sSL https://api.github.com/rate_limit"
2026-02-22 11:54:21 +01:00
else
2026-02-25 21:01:45 +01:00
msg_error " Failed to fetch release metadata (HTTP $http_code ) "
2026-02-22 11:54:21 +01:00
fi
2025-09-11 12:44:13 +02:00
return 1
2025-08-08 10:28:05 +02:00
fi
2025-04-28 15:25:10 +02:00
2025-09-11 12:44:13 +02:00
local json tag_name
json = $( </tmp/gh_rel.json)
tag_name = $( echo " $json " | jq -r '.tag_name // .name // empty' )
[ [ " $tag_name " = ~ ^v ] ] && version = " ${ tag_name : 1 } " || version = " $tag_name "
2025-05-05 15:47:43 +02:00
2025-09-11 12:44:13 +02:00
if [ [ " $current_version " = = " $version " ] ] ; then
$STD msg_ok " $app is already up-to-date (v $version ) "
return 0
2025-05-05 15:47:43 +02:00
fi
2025-04-28 15:25:10 +02:00
2025-09-11 12:44:13 +02:00
local tmpdir
tmpdir = $( mktemp -d) || return 1
local filename = "" url = ""
2025-04-28 15:25:10 +02:00
2025-09-11 12:44:13 +02:00
msg_info " Fetching GitHub release: $app ( $version ) "
2025-04-28 15:25:10 +02:00
2025-09-21 16:20:18 +02:00
local clean_install = false
[ [ -n " ${ CLEAN_INSTALL :- } " && " $CLEAN_INSTALL " = = "1" ] ] && clean_install = true
2025-09-11 12:44:13 +02:00
### Tarball Mode ###
if [ [ " $mode " = = "tarball" || " $mode " = = "source" ] ] ; then
2025-12-05 23:09:20 +01:00
# GitHub API's tarball_url/zipball_url can return HTTP 300 Multiple Choices
# when a branch and tag share the same name. Use explicit refs/tags/ URL instead.
local direct_tarball_url = " https://github.com/ $repo /archive/refs/tags/ $tag_name .tar.gz "
2025-09-11 12:44:13 +02:00
filename = " ${ app_lc } - ${ version } .tar.gz "
2025-04-28 15:25:10 +02:00
2025-12-05 23:09:20 +01:00
curl $download_timeout -fsSL -o " $tmpdir / $filename " " $direct_tarball_url " || {
msg_error " Download failed: $direct_tarball_url "
2025-09-11 12:44:13 +02:00
rm -rf " $tmpdir "
return 1
}
2025-05-15 15:18:41 +02:00
2025-09-11 12:44:13 +02:00
mkdir -p " $target "
2025-09-21 16:20:18 +02:00
if [ [ " ${ CLEAN_INSTALL :- 0 } " = = "1" ] ] ; then
rm -rf " ${ target : ? } / " *
fi
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
tar --no-same-owner -xzf " $tmpdir / $filename " -C " $tmpdir " || {
2025-10-22 06:25:26 -07:00
msg_error "Failed to extract tarball"
rm -rf " $tmpdir "
return 1
}
2025-09-11 12:44:13 +02:00
local unpack_dir
unpack_dir = $( find " $tmpdir " -mindepth 1 -maxdepth 1 -type d | head -n1)
2025-05-15 15:18:41 +02:00
2025-09-11 12:44:13 +02:00
shopt -s dotglob nullglob
cp -r " $unpack_dir " /* " $target / "
shopt -u dotglob nullglob
2025-05-05 15:47:43 +02:00
2025-09-11 12:44:13 +02:00
### Binary Mode ###
elif [ [ " $mode " = = "binary" ] ] ; then
local arch
arch = $( dpkg --print-architecture 2>/dev/null || uname -m)
[ [ " $arch " = = "x86_64" ] ] && arch = "amd64"
[ [ " $arch " = = "aarch64" ] ] && arch = "arm64"
2025-05-05 15:47:43 +02:00
2025-09-11 12:44:13 +02:00
local assets url_match = ""
assets = $( echo " $json " | jq -r '.assets[].browser_download_url' )
2025-05-05 15:47:43 +02:00
2025-09-11 12:44:13 +02:00
# If explicit filename pattern is provided (param $6), match that first
if [ [ -n " $asset_pattern " ] ] ; then
for u in $assets ; do
case " ${ u ##*/ } " in
$asset_pattern )
url_match = " $u "
break
; ;
esac
done
fi
2025-05-05 15:47:43 +02:00
2025-09-11 12:44:13 +02:00
# If no match via explicit pattern, fall back to architecture heuristic
if [ [ -z " $url_match " ] ] ; then
for u in $assets ; do
if [ [ " $u " = ~ ( $arch | amd64| x86_64| aarch64| arm64) .*\. deb$ ] ] ; then
url_match = " $u "
break
fi
done
fi
2025-05-05 15:47:43 +02:00
2025-09-11 12:44:13 +02:00
# Fallback: any .deb file
if [ [ -z " $url_match " ] ] ; then
for u in $assets ; do
[ [ " $u " = ~ \. deb$ ] ] && url_match = " $u " && break
done
fi
2025-05-05 15:47:43 +02:00
2026-02-07 20:37:50 +01:00
# Fallback: scan older releases for a matching .deb asset
if [ [ -z " $url_match " ] ] ; then
local fallback_json
if fallback_json = $( _gh_scan_older_releases " $repo " "binary" " $asset_pattern " " $tag_name " ) ; then
json = " $fallback_json "
tag_name = $( echo " $json " | jq -r '.tag_name // .name // empty' )
[ [ " $tag_name " = ~ ^v ] ] && version = " ${ tag_name : 1 } " || version = " $tag_name "
msg_info " Fetching GitHub release: $app ( $version ) "
assets = $( echo " $json " | jq -r '.assets[].browser_download_url' )
if [ [ -n " $asset_pattern " ] ] ; then
for u in $assets ; do
2026-02-22 11:54:21 +01:00
case " ${ u ##*/ } " in $asset_pattern )
url_match = " $u "
break
; ;
esac
2026-02-07 20:37:50 +01:00
done
fi
if [ [ -z " $url_match " ] ] ; then
for u in $assets ; do
2026-02-22 11:54:21 +01:00
if [ [ " $u " = ~ ( $arch | amd64| x86_64| aarch64| arm64) .*\. deb$ ] ] ; then
url_match = " $u "
break
fi
2026-02-07 20:37:50 +01:00
done
fi
if [ [ -z " $url_match " ] ] ; then
for u in $assets ; do
[ [ " $u " = ~ \. deb$ ] ] && url_match = " $u " && break
done
fi
fi
fi
2025-09-11 12:44:13 +02:00
if [ [ -z " $url_match " ] ] ; then
msg_error " No suitable .deb asset found for $app "
rm -rf " $tmpdir "
return 1
fi
2025-06-16 14:20:46 +02:00
2025-09-11 12:44:13 +02:00
filename = " ${ url_match ##*/ } "
curl $download_timeout -fsSL -o " $tmpdir / $filename " " $url_match " || {
msg_error " Download failed: $url_match "
rm -rf " $tmpdir "
return 1
}
chmod 644 " $tmpdir / $filename "
2026-01-28 13:25:07 +01:00
# SYSTEMD_OFFLINE=1 prevents systemd-tmpfiles failures in unprivileged LXC (Debian 13+/systemd 257+)
2026-01-29 12:43:54 +01:00
# Support DPKG_CONFOLD/DPKG_CONFNEW env vars for config file handling during .deb upgrades
local dpkg_opts = ""
[ [ " ${ DPKG_FORCE_CONFOLD :- } " = = "1" ] ] && dpkg_opts = "-o Dpkg::Options::=--force-confold"
[ [ " ${ DPKG_FORCE_CONFNEW :- } " = = "1" ] ] && dpkg_opts = "-o Dpkg::Options::=--force-confnew"
DEBIAN_FRONTEND = noninteractive SYSTEMD_OFFLINE = 1 $STD apt install -y $dpkg_opts " $tmpdir / $filename " || {
2026-01-28 13:25:07 +01:00
SYSTEMD_OFFLINE = 1 $STD dpkg -i " $tmpdir / $filename " || {
2025-09-11 12:44:13 +02:00
msg_error "Both apt and dpkg installation failed"
rm -rf " $tmpdir "
return 1
}
}
2025-09-21 16:20:18 +02:00
### Prebuild Mode ###
2025-09-11 12:44:13 +02:00
elif [ [ " $mode " = = "prebuild" ] ] ; then
local pattern = " ${ 6 % \" } "
pattern = " ${ pattern # \" } "
[ [ -z " $pattern " ] ] && {
msg_error "Mode 'prebuild' requires 6th parameter (asset filename pattern)"
rm -rf " $tmpdir "
return 1
}
local asset_url = ""
for u in $( echo " $json " | jq -r '.assets[].browser_download_url' ) ; do
filename_candidate = " ${ u ##*/ } "
case " $filename_candidate " in
$pattern )
asset_url = " $u "
break
; ;
esac
done
2026-02-07 20:37:50 +01:00
# Fallback: scan older releases for a matching asset
if [ [ -z " $asset_url " ] ] ; then
local fallback_json
if fallback_json = $( _gh_scan_older_releases " $repo " "prebuild" " $pattern " " $tag_name " ) ; then
json = " $fallback_json "
tag_name = $( echo " $json " | jq -r '.tag_name // .name // empty' )
[ [ " $tag_name " = ~ ^v ] ] && version = " ${ tag_name : 1 } " || version = " $tag_name "
msg_info " Fetching GitHub release: $app ( $version ) "
for u in $( echo " $json " | jq -r '.assets[].browser_download_url' ) ; do
filename_candidate = " ${ u ##*/ } "
2026-02-22 11:54:21 +01:00
case " $filename_candidate " in $pattern )
asset_url = " $u "
break
; ;
esac
2026-02-07 20:37:50 +01:00
done
fi
fi
2025-09-11 12:44:13 +02:00
[ [ -z " $asset_url " ] ] && {
msg_error " No asset matching ' $pattern ' found "
rm -rf " $tmpdir "
return 1
}
filename = " ${ asset_url ##*/ } "
curl $download_timeout -fsSL -o " $tmpdir / $filename " " $asset_url " || {
msg_error " Download failed: $asset_url "
rm -rf " $tmpdir "
return 1
}
local unpack_tmp
unpack_tmp = $( mktemp -d)
mkdir -p " $target "
2025-09-21 16:20:18 +02:00
if [ [ " ${ CLEAN_INSTALL :- 0 } " = = "1" ] ] ; then
rm -rf " ${ target : ? } / " *
fi
2025-09-11 12:44:13 +02:00
if [ [ " $filename " = = *.zip ] ] ; then
2025-10-22 06:25:26 -07:00
ensure_dependencies unzip
unzip -q " $tmpdir / $filename " -d " $unpack_tmp " || {
msg_error "Failed to extract ZIP archive"
rm -rf " $tmpdir " " $unpack_tmp "
return 1
}
2026-01-23 21:54:23 +01:00
elif [ [ " $filename " = = *.tar.* || " $filename " = = *.tgz || " $filename " = = *.txz ] ] ; then
2025-10-23 06:46:28 -07:00
tar --no-same-owner -xf " $tmpdir / $filename " -C " $unpack_tmp " || {
2025-10-22 06:25:26 -07:00
msg_error "Failed to extract TAR archive"
rm -rf " $tmpdir " " $unpack_tmp "
return 1
}
2025-07-22 13:14:09 +02:00
else
2025-09-11 12:44:13 +02:00
msg_error " Unsupported archive format: $filename "
rm -rf " $tmpdir " " $unpack_tmp "
return 1
2025-07-22 13:14:09 +02:00
fi
2025-05-05 15:47:43 +02:00
2025-09-11 12:44:13 +02:00
local top_dirs
top_dirs = $( find " $unpack_tmp " -mindepth 1 -maxdepth 1 -type d | wc -l)
local top_entries inner_dir
top_entries = $( find " $unpack_tmp " -mindepth 1 -maxdepth 1)
if [ [ " $( echo " $top_entries " | wc -l) " -eq 1 && -d " $top_entries " ] ] ; then
# Strip leading folder
inner_dir = " $top_entries "
shopt -s dotglob nullglob
if compgen -G " $inner_dir /* " >/dev/null; then
cp -r " $inner_dir " /* " $target / " || {
msg_error " Failed to copy contents from $inner_dir to $target "
rm -rf " $tmpdir " " $unpack_tmp "
return 1
}
else
msg_error " Inner directory is empty: $inner_dir "
rm -rf " $tmpdir " " $unpack_tmp "
return 1
fi
shopt -u dotglob nullglob
2025-07-22 15:55:56 +02:00
else
2025-09-11 12:44:13 +02:00
# Copy all contents
shopt -s dotglob nullglob
if compgen -G " $unpack_tmp /* " >/dev/null; then
cp -r " $unpack_tmp " /* " $target / " || {
msg_error " Failed to copy contents to $target "
rm -rf " $tmpdir " " $unpack_tmp "
return 1
}
else
msg_error "Unpacked archive is empty"
rm -rf " $tmpdir " " $unpack_tmp "
return 1
fi
shopt -u dotglob nullglob
2025-05-05 15:47:43 +02:00
fi
2025-09-11 12:44:13 +02:00
### Singlefile Mode ###
elif [ [ " $mode " = = "singlefile" ] ] ; then
local pattern = " ${ 6 % \" } "
pattern = " ${ pattern # \" } "
[ [ -z " $pattern " ] ] && {
msg_error "Mode 'singlefile' requires 6th parameter (asset filename pattern)"
rm -rf " $tmpdir "
return 1
}
local asset_url = ""
for u in $( echo " $json " | jq -r '.assets[].browser_download_url' ) ; do
filename_candidate = " ${ u ##*/ } "
case " $filename_candidate " in
$pattern )
asset_url = " $u "
break
; ;
esac
done
2026-02-07 20:37:50 +01:00
# Fallback: scan older releases for a matching asset
if [ [ -z " $asset_url " ] ] ; then
local fallback_json
if fallback_json = $( _gh_scan_older_releases " $repo " "singlefile" " $pattern " " $tag_name " ) ; then
json = " $fallback_json "
tag_name = $( echo " $json " | jq -r '.tag_name // .name // empty' )
[ [ " $tag_name " = ~ ^v ] ] && version = " ${ tag_name : 1 } " || version = " $tag_name "
msg_info " Fetching GitHub release: $app ( $version ) "
for u in $( echo " $json " | jq -r '.assets[].browser_download_url' ) ; do
filename_candidate = " ${ u ##*/ } "
2026-02-22 11:54:21 +01:00
case " $filename_candidate " in $pattern )
asset_url = " $u "
break
; ;
esac
2026-02-07 20:37:50 +01:00
done
fi
fi
2025-09-11 12:44:13 +02:00
[ [ -z " $asset_url " ] ] && {
msg_error " No asset matching ' $pattern ' found "
rm -rf " $tmpdir "
return 1
}
filename = " ${ asset_url ##*/ } "
mkdir -p " $target "
local use_filename = " ${ USE_ORIGINAL_FILENAME :- false } "
local target_file = " $app "
[ [ " $use_filename " = = "true" ] ] && target_file = " $filename "
curl $download_timeout -fsSL -o " $target / $target_file " " $asset_url " || {
msg_error " Download failed: $asset_url "
rm -rf " $tmpdir "
return 1
}
if [ [ " $target_file " != *.jar && -f " $target / $target_file " ] ] ; then
chmod +x " $target / $target_file "
fi
else
msg_error " Unknown mode: $mode "
rm -rf " $tmpdir "
return 1
2025-05-05 15:47:43 +02:00
fi
2025-09-11 12:44:13 +02:00
echo " $version " >" $version_file "
msg_ok " Deployed: $app ( $version ) "
rm -rf " $tmpdir "
}
2025-05-05 15:47:43 +02:00
2025-09-11 12:44:13 +02:00
# ------------------------------------------------------------------------------
# Installs Adminer (Debian/Ubuntu via APT, Alpine via direct download).
#
# Description:
# - Adds Adminer to Apache or web root
# - Supports Alpine and Debian-based systems
# ------------------------------------------------------------------------------
function setup_adminer( ) {
if grep -qi alpine /etc/os-release; then
msg_info "Setup Adminer (Alpine)"
mkdir -p /var/www/localhost/htdocs/adminer
2025-10-22 06:25:26 -07:00
curl -fsSL https://github.com/vrana/adminer/releases/latest/download/adminer.php \
-o /var/www/localhost/htdocs/adminer/index.php || {
2025-09-11 12:44:13 +02:00
msg_error "Failed to download Adminer"
return 1
2025-10-22 06:25:26 -07:00
}
cache_installed_version "adminer" "latest-alpine"
msg_ok "Setup Adminer (Alpine)"
2025-09-11 12:44:13 +02:00
else
msg_info "Setup Adminer (Debian/Ubuntu)"
2025-10-22 06:25:26 -07:00
ensure_dependencies adminer
$STD a2enconf adminer || {
msg_error "Failed to enable Adminer Apache config"
return 1
}
$STD systemctl reload apache2 || {
msg_error "Failed to reload Apache"
return 1
}
local VERSION
2025-12-18 18:38:08 +01:00
VERSION = $( dpkg -s adminer 2>/dev/null | grep '^Version:' | awk '{print $2}' 2>/dev/null || echo 'unknown' )
2025-10-22 06:25:26 -07:00
cache_installed_version "adminer" " ${ VERSION :- unknown } "
msg_ok "Setup Adminer (Debian/Ubuntu)"
2025-07-22 13:14:09 +02:00
fi
2025-04-28 15:25:10 +02:00
}
2025-08-04 14:12:18 +02:00
2025-05-15 15:18:41 +02:00
# ------------------------------------------------------------------------------
2025-08-04 14:12:18 +02:00
# Installs or updates Composer globally (robust, idempotent).
2025-05-15 15:18:41 +02:00
#
2025-08-04 14:12:18 +02:00
# - Installs to /usr/local/bin/composer
# - Removes old binaries/symlinks in /usr/bin, /bin, /root/.composer, etc.
# - Ensures /usr/local/bin is in PATH (permanent)
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# - Auto-updates to latest version
2025-05-15 15:18:41 +02:00
# ------------------------------------------------------------------------------
2025-06-18 12:07:08 +02:00
function setup_composer( ) {
2025-05-05 15:47:43 +02:00
local COMPOSER_BIN = "/usr/local/bin/composer"
export COMPOSER_ALLOW_SUPERUSER = 1
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Get currently installed version
local INSTALLED_VERSION = ""
if [ [ -x " $COMPOSER_BIN " ] ] ; then
INSTALLED_VERSION = $( " $COMPOSER_BIN " --version 2>/dev/null | awk '{print $3}' )
fi
# Scenario 1: Already installed - just self-update
if [ [ -n " $INSTALLED_VERSION " ] ] ; then
msg_info " Update Composer $INSTALLED_VERSION "
$STD " $COMPOSER_BIN " self-update --no-interaction || true
local UPDATED_VERSION
UPDATED_VERSION = $( " $COMPOSER_BIN " --version 2>/dev/null | awk '{print $3}' )
cache_installed_version "composer" " $UPDATED_VERSION "
msg_ok " Update Composer $UPDATED_VERSION "
return 0
fi
# Scenario 2: Fresh install
2025-10-22 06:25:26 -07:00
msg_info "Setup Composer"
2025-08-04 14:12:18 +02:00
for old in /usr/bin/composer /bin/composer /root/.composer/vendor/bin/composer; do
[ [ -e " $old " && " $old " != " $COMPOSER_BIN " ] ] && rm -f " $old "
done
ensure_usr_local_bin_persist
export PATH = " /usr/local/bin: $PATH "
2025-10-22 06:25:26 -07:00
curl -fsSL https://getcomposer.org/installer -o /tmp/composer-setup.php || {
msg_error "Failed to download Composer installer"
return 1
}
2025-05-05 15:47:43 +02:00
2025-10-22 06:25:26 -07:00
$STD php /tmp/composer-setup.php --install-dir= /usr/local/bin --filename= composer || {
msg_error "Failed to install Composer"
rm -f /tmp/composer-setup.php
return 1
}
rm -f /tmp/composer-setup.php
2025-05-05 15:47:43 +02:00
2025-08-04 14:12:18 +02:00
if [ [ ! -x " $COMPOSER_BIN " ] ] ; then
2025-10-22 06:25:26 -07:00
msg_error "Composer installation failed"
2025-05-05 15:47:43 +02:00
return 1
fi
2025-04-28 15:25:10 +02:00
2025-05-05 15:47:43 +02:00
chmod +x " $COMPOSER_BIN "
2025-10-22 06:25:26 -07:00
$STD " $COMPOSER_BIN " self-update --no-interaction || true
local FINAL_VERSION
FINAL_VERSION = $( " $COMPOSER_BIN " --version 2>/dev/null | awk '{print $3}' )
cache_installed_version "composer" " $FINAL_VERSION "
msg_ok "Setup Composer"
2025-04-28 15:25:10 +02:00
}
2025-09-11 12:44:13 +02:00
# ------------------------------------------------------------------------------
# Installs FFmpeg from source or prebuilt binary (Debian/Ubuntu only).
#
# Description:
# - Downloads and builds FFmpeg from GitHub (https://github.com/FFmpeg/FFmpeg)
# - Supports specific version override via FFMPEG_VERSION (e.g. n7.1.1)
# - Supports build profile via FFMPEG_TYPE:
# - minimal : x264, vpx, mp3 only
# - medium : adds subtitles, fonts, opus, vorbis
# - full : adds dav1d, svt-av1, zlib, numa
# - binary : downloads static build (johnvansickle.com)
# - Defaults to latest stable version and full feature set
#
# Notes:
# - Requires: curl, jq, build-essential, and matching codec libraries
# - Result is installed to /usr/local/bin/ffmpeg
# ------------------------------------------------------------------------------
function setup_ffmpeg( ) {
2025-10-22 06:25:26 -07:00
local TMP_DIR = $( mktemp -d)
2025-09-11 12:44:13 +02:00
local GITHUB_REPO = "FFmpeg/FFmpeg"
local VERSION = " ${ FFMPEG_VERSION :- latest } "
local TYPE = " ${ FFMPEG_TYPE :- full } "
local BIN_PATH = "/usr/local/bin/ffmpeg"
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Get currently installed version
local INSTALLED_VERSION = ""
if command -v ffmpeg & >/dev/null; then
INSTALLED_VERSION = $( ffmpeg -version 2>/dev/null | head -n1 | awk '{print $3}' )
fi
msg_info " Setup FFmpeg ${ VERSION } ( $TYPE ) "
2025-09-11 12:44:13 +02:00
# Binary fallback mode
if [ [ " $TYPE " = = "binary" ] ] ; then
2025-10-22 06:25:26 -07:00
curl -fsSL https://johnvansickle.com/ffmpeg/releases/ffmpeg-release-amd64-static.tar.xz -o " $TMP_DIR /ffmpeg.tar.xz " || {
msg_error "Failed to download FFmpeg binary"
rm -rf " $TMP_DIR "
return 1
}
tar -xf " $TMP_DIR /ffmpeg.tar.xz " -C " $TMP_DIR " || {
msg_error "Failed to extract FFmpeg binary"
rm -rf " $TMP_DIR "
return 1
}
2025-09-11 12:44:13 +02:00
local EXTRACTED_DIR
EXTRACTED_DIR = $( find " $TMP_DIR " -maxdepth 1 -type d -name "ffmpeg-*" )
cp " $EXTRACTED_DIR /ffmpeg " " $BIN_PATH "
cp " $EXTRACTED_DIR /ffprobe " /usr/local/bin/ffprobe
chmod +x " $BIN_PATH " /usr/local/bin/ffprobe
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
local FINAL_VERSION = $( $BIN_PATH -version 2>/dev/null | head -n1 | awk '{print $3}' )
2025-09-11 12:44:13 +02:00
rm -rf " $TMP_DIR "
2025-10-22 06:25:26 -07:00
cache_installed_version "ffmpeg" " $FINAL_VERSION "
ensure_usr_local_bin_persist
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
[ [ -n " $INSTALLED_VERSION " ] ] && msg_ok " Upgrade FFmpeg $INSTALLED_VERSION → $FINAL_VERSION " || msg_ok " Setup FFmpeg $FINAL_VERSION "
2025-10-22 06:25:26 -07:00
return 0
2025-09-11 12:44:13 +02:00
fi
2025-10-22 06:25:26 -07:00
ensure_dependencies jq
2025-09-11 12:44:13 +02:00
# Auto-detect latest stable version if none specified
if [ [ " $VERSION " = = "latest" || -z " $VERSION " ] ] ; then
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
local ffmpeg_tags
ffmpeg_tags = $( curl -fsSL --max-time 15 " https://api.github.com/repos/ ${ GITHUB_REPO } /tags " 2>/dev/null || echo "" )
if [ [ -z " $ffmpeg_tags " ] ] ; then
msg_warn "Could not fetch FFmpeg versions from GitHub, trying binary fallback"
VERSION = "" # Will trigger binary fallback below
else
VERSION = $( echo " $ffmpeg_tags " | jq -r '.[].name' 2>/dev/null |
grep -E '^n[0-9]+\.[0-9]+\.[0-9]+$' |
sort -V | tail -n1 || echo "" )
fi
2025-09-11 12:44:13 +02:00
fi
if [ [ -z " $VERSION " ] ] ; then
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
msg_info "Could not determine FFmpeg source version, using pre-built binary"
VERSION = "" # Will use binary fallback
2025-09-11 12:44:13 +02:00
fi
# Dependency selection
local DEPS = ( build-essential yasm nasm pkg-config)
case " $TYPE " in
minimal)
DEPS += ( libx264-dev libvpx-dev libmp3lame-dev)
; ;
medium)
DEPS += ( libx264-dev libvpx-dev libmp3lame-dev libfreetype6-dev libass-dev libopus-dev libvorbis-dev)
; ;
full)
DEPS += (
libx264-dev libx265-dev libvpx-dev libmp3lame-dev
libfreetype6-dev libass-dev libopus-dev libvorbis-dev
libdav1d-dev libsvtav1-dev zlib1g-dev libnuma-dev
libva-dev libdrm-dev
)
; ;
*)
msg_error " Invalid FFMPEG_TYPE: $TYPE "
rm -rf " $TMP_DIR "
return 1
; ;
esac
2025-10-22 06:25:26 -07:00
ensure_dependencies " ${ DEPS [@] } "
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Try to download source if VERSION is set
if [ [ -n " $VERSION " ] ] ; then
curl -fsSL " https://github.com/ ${ GITHUB_REPO } /archive/refs/tags/ ${ VERSION } .tar.gz " -o " $TMP_DIR /ffmpeg.tar.gz " || {
msg_warn " Failed to download FFmpeg source ${ VERSION } , falling back to pre-built binary "
VERSION = ""
}
fi
# If no source download (either VERSION empty or download failed), use binary
if [ [ -z " $VERSION " ] ] ; then
msg_info "Setup FFmpeg from pre-built binary"
curl -fsSL https://johnvansickle.com/ffmpeg/releases/ffmpeg-release-amd64-static.tar.xz -o " $TMP_DIR /ffmpeg.tar.xz " || {
msg_error "Failed to download FFmpeg pre-built binary"
rm -rf " $TMP_DIR "
return 1
}
tar -xJf " $TMP_DIR /ffmpeg.tar.xz " -C " $TMP_DIR " || {
msg_error "Failed to extract FFmpeg binary archive"
rm -rf " $TMP_DIR "
return 1
}
if ! cp " $TMP_DIR /ffmpeg- " */ffmpeg /usr/local/bin/ffmpeg 2>/dev/null; then
msg_error "Failed to install FFmpeg binary"
rm -rf " $TMP_DIR "
return 1
fi
cache_installed_version "ffmpeg" "static"
2025-10-22 06:25:26 -07:00
rm -rf " $TMP_DIR "
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
msg_ok "Setup FFmpeg from pre-built binary"
return 0
fi
2025-10-22 06:25:26 -07:00
tar -xzf " $TMP_DIR /ffmpeg.tar.gz " -C " $TMP_DIR " || {
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
msg_error "Failed to extract FFmpeg source"
2025-10-22 06:25:26 -07:00
rm -rf " $TMP_DIR "
return 1
}
2025-09-11 12:44:13 +02:00
cd " $TMP_DIR /FFmpeg- " * || {
msg_error "Source extraction failed"
rm -rf " $TMP_DIR "
return 1
}
local args = (
--enable-gpl
--enable-shared
--enable-nonfree
--disable-static
--enable-libx264
--enable-libvpx
--enable-libmp3lame
)
if [ [ " $TYPE " != "minimal" ] ] ; then
args += ( --enable-libfreetype --enable-libass --enable-libopus --enable-libvorbis)
fi
if [ [ " $TYPE " = = "full" ] ] ; then
args += ( --enable-libx265 --enable-libdav1d --enable-zlib)
args += ( --enable-vaapi --enable-libdrm)
fi
if [ [ ${# args [@] } -eq 0 ] ] ; then
2025-10-22 06:25:26 -07:00
msg_error "FFmpeg configure args array is empty"
2025-09-11 12:44:13 +02:00
rm -rf " $TMP_DIR "
return 1
fi
2025-10-22 06:25:26 -07:00
$STD ./configure " ${ args [@] } " || {
msg_error "FFmpeg configure failed"
rm -rf " $TMP_DIR "
return 1
}
$STD make -j" $( nproc) " || {
msg_error "FFmpeg compilation failed"
rm -rf " $TMP_DIR "
return 1
}
$STD make install || {
msg_error "FFmpeg installation failed"
2025-09-11 12:44:13 +02:00
rm -rf " $TMP_DIR "
return 1
}
echo "/usr/local/lib" >/etc/ld.so.conf.d/ffmpeg.conf
2025-10-22 06:25:26 -07:00
$STD ldconfig
2025-09-11 12:44:13 +02:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
ldconfig -p 2>/dev/null | grep libavdevice >/dev/null || {
2025-09-11 12:44:13 +02:00
msg_error "libavdevice not registered with dynamic linker"
2025-10-22 06:25:26 -07:00
rm -rf " $TMP_DIR "
2025-09-11 12:44:13 +02:00
return 1
}
if ! command -v ffmpeg & >/dev/null; then
msg_error "FFmpeg installation failed"
rm -rf " $TMP_DIR "
return 1
fi
local FINAL_VERSION
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
FINAL_VERSION = $( ffmpeg -version 2>/dev/null | head -n1 | awk '{print $3}' )
2025-09-11 12:44:13 +02:00
rm -rf " $TMP_DIR "
2025-10-22 06:25:26 -07:00
cache_installed_version "ffmpeg" " $FINAL_VERSION "
2025-09-11 12:44:13 +02:00
ensure_usr_local_bin_persist
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
[ [ -n " $INSTALLED_VERSION " ] ] && msg_ok " Upgrade FFmpeg $INSTALLED_VERSION → $FINAL_VERSION " || msg_ok " Setup FFmpeg $FINAL_VERSION "
2025-09-11 12:44:13 +02:00
}
2025-05-15 15:18:41 +02:00
# ------------------------------------------------------------------------------
# Installs Go (Golang) from official tarball.
#
# Description:
# - Determines system architecture
# - Downloads latest version if GO_VERSION not set
#
# Variables:
# GO_VERSION - Version to install (e.g. 1.22.2 or latest)
# ------------------------------------------------------------------------------
2025-06-18 12:07:08 +02:00
function setup_go( ) {
2025-05-05 15:47:43 +02:00
local ARCH
case " $( uname -m) " in
x86_64) ARCH = "amd64" ; ;
aarch64) ARCH = "arm64" ; ;
*)
msg_error " Unsupported architecture: $( uname -m) "
return 1
; ;
esac
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Resolve "latest" version
local GO_VERSION = " ${ GO_VERSION :- latest } "
if [ [ " $GO_VERSION " = = "latest" ] ] ; then
GO_VERSION = $( curl -fsSL https://go.dev/VERSION?m= text 2>/dev/null | head -n1 | sed 's/^go//' ) || {
2025-05-05 15:47:43 +02:00
msg_error "Could not determine latest Go version"
return 1
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
}
[ [ -z " $GO_VERSION " ] ] && {
msg_error "Latest Go version is empty"
return 1
}
2025-05-05 15:47:43 +02:00
fi
local GO_BIN = "/usr/local/bin/go"
local GO_INSTALL_DIR = "/usr/local/go"
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Get currently installed version
local CURRENT_VERSION = ""
2025-05-05 15:47:43 +02:00
if [ [ -x " $GO_BIN " ] ] ; then
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
CURRENT_VERSION = $( " $GO_BIN " version 2>/dev/null | awk '{print $3}' | sed 's/go//' )
fi
# Scenario 1: Already at target version
if [ [ -n " $CURRENT_VERSION " && " $CURRENT_VERSION " = = " $GO_VERSION " ] ] ; then
cache_installed_version "go" " $GO_VERSION "
return 0
2025-05-05 15:47:43 +02:00
fi
2025-04-28 15:25:10 +02:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Scenario 2: Different version or not installed
if [ [ -n " $CURRENT_VERSION " && " $CURRENT_VERSION " != " $GO_VERSION " ] ] ; then
msg_info " Upgrade Go from $CURRENT_VERSION to $GO_VERSION "
remove_old_tool_version "go"
else
msg_info " Setup Go $GO_VERSION "
fi
2025-10-22 06:25:26 -07:00
2025-09-11 12:44:13 +02:00
local TARBALL = " go ${ GO_VERSION } .linux- ${ ARCH } .tar.gz "
local URL = " https://go.dev/dl/ ${ TARBALL } "
local TMP_TAR = $( mktemp)
curl -fsSL " $URL " -o " $TMP_TAR " || {
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
msg_error " Failed to download Go $GO_VERSION "
2025-10-22 06:25:26 -07:00
rm -f " $TMP_TAR "
2025-09-11 12:44:13 +02:00
return 1
}
2025-10-22 06:25:26 -07:00
$STD tar -C /usr/local -xzf " $TMP_TAR " || {
msg_error "Failed to extract Go tarball"
rm -f " $TMP_TAR "
return 1
}
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
2025-09-11 12:44:13 +02:00
ln -sf /usr/local/go/bin/go /usr/local/bin/go
ln -sf /usr/local/go/bin/gofmt /usr/local/bin/gofmt
rm -f " $TMP_TAR "
2025-10-22 06:25:26 -07:00
cache_installed_version "go" " $GO_VERSION "
ensure_usr_local_bin_persist
2025-09-11 12:44:13 +02:00
msg_ok " Setup Go $GO_VERSION "
}
# ------------------------------------------------------------------------------
# Installs or updates Ghostscript (gs) from source.
#
# Description:
# - Fetches latest release
# - Builds and installs system-wide
# ------------------------------------------------------------------------------
function setup_gs( ) {
2025-10-22 06:25:26 -07:00
local TMP_DIR = $( mktemp -d)
local CURRENT_VERSION = $( gs --version 2>/dev/null || echo "0" )
ensure_dependencies jq
2025-09-11 12:44:13 +02:00
2025-10-22 06:25:26 -07:00
local RELEASE_JSON
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
RELEASE_JSON = $( curl -fsSL --max-time 15 https://api.github.com/repos/ArtifexSoftware/ghostpdl-downloads/releases/latest 2>/dev/null || echo "" )
if [ [ -z " $RELEASE_JSON " ] ] ; then
msg_warn "Cannot fetch latest Ghostscript version from GitHub API"
# Try to get from current version
if command -v gs & >/dev/null; then
gs --version | head -n1
cache_installed_version "ghostscript" " $CURRENT_VERSION "
return 0
fi
msg_error "Cannot determine Ghostscript version and no existing installation found"
return 1
fi
2025-10-22 06:25:26 -07:00
local LATEST_VERSION
LATEST_VERSION = $( echo " $RELEASE_JSON " | jq -r '.tag_name' | sed 's/^gs//' )
local LATEST_VERSION_DOTTED
LATEST_VERSION_DOTTED = $( echo " $RELEASE_JSON " | jq -r '.name' | grep -o '[0-9]\+\.[0-9]\+\.[0-9]\+' )
2025-09-11 12:44:13 +02:00
2025-10-22 06:25:26 -07:00
if [ [ -z " $LATEST_VERSION " || -z " $LATEST_VERSION_DOTTED " ] ] ; then
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
msg_warn "Could not determine latest Ghostscript version from GitHub - checking system"
# Fallback: try to use system version or return error
if [ [ " $CURRENT_VERSION " = = "0" ] ] ; then
msg_error "Ghostscript not installed and cannot determine latest version"
rm -rf " $TMP_DIR "
return 1
fi
2025-09-11 12:44:13 +02:00
rm -rf " $TMP_DIR "
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
return 0
2025-09-11 12:44:13 +02:00
fi
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Scenario 1: Already at latest version
if [ [ -n " $LATEST_VERSION_DOTTED " ] ] && dpkg --compare-versions " $CURRENT_VERSION " ge " $LATEST_VERSION_DOTTED " 2>/dev/null; then
2025-10-22 06:25:26 -07:00
cache_installed_version "ghostscript" " $LATEST_VERSION_DOTTED "
2025-09-11 12:44:13 +02:00
rm -rf " $TMP_DIR "
2025-10-22 06:25:26 -07:00
return 0
2025-09-11 12:44:13 +02:00
fi
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Scenario 2: New install or upgrade
if [ [ " $CURRENT_VERSION " != "0" && " $CURRENT_VERSION " != " $LATEST_VERSION_DOTTED " ] ] ; then
msg_info " Upgrade Ghostscript from $CURRENT_VERSION to $LATEST_VERSION_DOTTED "
else
msg_info " Setup Ghostscript $LATEST_VERSION_DOTTED "
fi
2025-10-22 06:25:26 -07:00
curl -fsSL " https://github.com/ArtifexSoftware/ghostpdl-downloads/releases/download/gs ${ LATEST_VERSION } /ghostscript- ${ LATEST_VERSION_DOTTED } .tar.gz " -o " $TMP_DIR /ghostscript.tar.gz " || {
msg_error "Failed to download Ghostscript"
rm -rf " $TMP_DIR "
return 1
}
2025-09-11 12:44:13 +02:00
if ! tar -xzf " $TMP_DIR /ghostscript.tar.gz " -C " $TMP_DIR " ; then
2025-10-22 06:25:26 -07:00
msg_error "Failed to extract Ghostscript archive"
2025-09-11 12:44:13 +02:00
rm -rf " $TMP_DIR "
2025-10-22 06:25:26 -07:00
return 1
2025-09-11 12:44:13 +02:00
fi
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Verify directory exists before cd
if [ [ ! -d " $TMP_DIR /ghostscript- ${ LATEST_VERSION_DOTTED } " ] ] ; then
msg_error " Ghostscript source directory not found: $TMP_DIR /ghostscript- ${ LATEST_VERSION_DOTTED } "
rm -rf " $TMP_DIR "
return 1
fi
2025-09-11 12:44:13 +02:00
cd " $TMP_DIR /ghostscript- ${ LATEST_VERSION_DOTTED } " || {
2025-10-22 06:25:26 -07:00
msg_error "Failed to enter Ghostscript source directory"
rm -rf " $TMP_DIR "
return 1
}
ensure_dependencies build-essential libpng-dev zlib1g-dev
$STD ./configure || {
msg_error "Ghostscript configure failed"
rm -rf " $TMP_DIR "
return 1
}
$STD make -j" $( nproc) " || {
msg_error "Ghostscript compilation failed"
rm -rf " $TMP_DIR "
return 1
}
$STD make install || {
msg_error "Ghostscript installation failed"
2025-09-11 12:44:13 +02:00
rm -rf " $TMP_DIR "
2025-10-22 06:25:26 -07:00
return 1
2025-09-11 12:44:13 +02:00
}
2025-10-22 06:25:26 -07:00
2025-09-11 12:44:13 +02:00
hash -r
if [ [ ! -x " $( command -v gs) " ] ] ; then
if [ [ -x /usr/local/bin/gs ] ] ; then
ln -sf /usr/local/bin/gs /usr/bin/gs
fi
fi
rm -rf " $TMP_DIR "
2025-10-22 06:25:26 -07:00
cache_installed_version "ghostscript" " $LATEST_VERSION_DOTTED "
ensure_usr_local_bin_persist
msg_ok " Setup Ghostscript $LATEST_VERSION_DOTTED "
}
2025-09-11 12:44:13 +02:00
2025-10-22 06:25:26 -07:00
# ------------------------------------------------------------------------------
# Sets up Hardware Acceleration on debian or ubuntu.
#
# Description:
2026-01-06 19:27:04 +01:00
# - Detects all available GPUs (Intel, AMD, NVIDIA)
# - Allows user to select which GPU(s) to configure (with 60s timeout)
# - Installs the correct libraries and packages for each GPU type
# - Supports: Debian 11/12/13, Ubuntu 22.04/24.04
# - Intel: Legacy (Gen 6-8), Modern (Gen 9+), Arc
# - AMD: Discrete GPUs, APUs, ROCm compute
# - NVIDIA: Version-matched drivers from CUDA repository
2025-10-22 06:25:26 -07:00
#
# Notes:
2026-01-06 19:27:04 +01:00
# - Some Intel packages are fetched from GitHub due to missing Debian packages
# - NVIDIA requires matching host driver version
2025-10-22 06:25:26 -07:00
# ------------------------------------------------------------------------------
function setup_hwaccel( ) {
2026-01-05 18:03:02 +01:00
# Check if user explicitly disabled GPU in advanced settings
2026-01-06 20:15:22 +01:00
# ENABLE_GPU is exported from build.func
if [ [ " ${ ENABLE_GPU :- no } " = = "no" ] ] ; then
2026-01-05 18:03:02 +01:00
return 0
fi
2025-12-22 23:27:37 +01:00
# Check if GPU passthrough is enabled (device nodes must exist)
if [ [ ! -d /dev/dri && ! -e /dev/nvidia0 && ! -e /dev/kfd ] ] ; then
msg_warn "No GPU passthrough detected (/dev/dri, /dev/nvidia*, /dev/kfd not found) - skipping hardware acceleration setup"
return 0
fi
2025-10-22 06:25:26 -07:00
msg_info "Setup Hardware Acceleration"
2026-01-06 19:27:04 +01:00
# Install pciutils if needed
2025-10-22 06:25:26 -07:00
if ! command -v lspci & >/dev/null; then
2026-01-06 19:27:04 +01:00
$STD apt -y update || {
msg_warn "Failed to update package list"
2026-01-05 18:03:02 +01:00
return 0
2026-01-06 19:27:04 +01:00
}
$STD apt -y install pciutils || {
msg_warn "Failed to install pciutils"
2026-01-05 18:03:02 +01:00
return 0
2026-01-06 19:27:04 +01:00
}
2025-10-22 06:25:26 -07:00
fi
2026-01-06 19:27:04 +01:00
# ═══════════════════════════════════════════════════════════════════════════
# GPU Detection - Build list of all available GPUs with details
# ═══════════════════════════════════════════════════════════════════════════
local -a GPU_LIST = ( )
local -a GPU_TYPES = ( )
local -a GPU_NAMES = ( )
local gpu_count = 0
# Get all GPU entries from lspci
while IFS = read -r line; do
[ [ -z " $line " ] ] && continue
local pci_addr gpu_name gpu_type = ""
pci_addr = $( echo " $line " | awk '{print $1}' )
gpu_name = $( echo " $line " | sed 's/^[^ ]* [^:]*: //' )
# Determine GPU type
# Note: Use -w (word boundary) for ATI to avoid matching "CorporATIon"
if echo " $gpu_name " | grep -qi 'Intel' ; then
gpu_type = "INTEL"
# Subtype detection for Intel
# Order matters: Check Arc first, then Gen9+ (UHD/Iris/HD 5xx-6xx), then Legacy (HD 2xxx-5xxx)
# HD Graphics 530/630 = Gen 9 (Skylake/Kaby Lake) - 3 digits
# HD Graphics 4600/5500 = Gen 7-8 (Haswell/Broadwell) - 4 digits starting with 2-5
if echo " $gpu_name " | grep -qiE 'Arc|DG[12]' ; then
gpu_type = "INTEL_ARC"
elif echo " $gpu_name " | grep -qiE 'UHD|Iris|HD Graphics [5-6][0-9]{2}[^0-9]|HD Graphics [5-6][0-9]{2}$' ; then
# HD Graphics 5xx/6xx (3 digits) = Gen 9+ (Skylake onwards)
gpu_type = "INTEL_GEN9+"
elif echo " $gpu_name " | grep -qiE 'HD Graphics [2-5][0-9]{3}' ; then
# HD Graphics 2xxx-5xxx (4 digits) = Gen 6-8 Legacy
gpu_type = "INTEL_LEGACY"
fi
elif echo " $gpu_name " | grep -qiwE 'AMD|ATI|Radeon|Advanced Micro Devices' ; then
gpu_type = "AMD"
elif echo " $gpu_name " | grep -qi 'NVIDIA' ; then
gpu_type = "NVIDIA"
fi
2025-10-22 06:25:26 -07:00
2026-01-06 19:27:04 +01:00
if [ [ -n " $gpu_type " ] ] ; then
GPU_LIST += ( " $pci_addr " )
GPU_TYPES += ( " $gpu_type " )
GPU_NAMES += ( " $gpu_name " )
2026-01-06 20:32:15 +01:00
( ( gpu_count++) ) || true
2026-01-06 19:27:04 +01:00
fi
done < <( lspci 2>/dev/null | grep -Ei 'vga|3d|display' )
# Check for AMD APU via CPU vendor if no discrete GPU found
2025-10-22 06:25:26 -07:00
local cpu_vendor
2025-12-18 18:38:08 +01:00
cpu_vendor = $( lscpu 2>/dev/null | grep -i 'Vendor ID' | awk '{print $3}' 2>/dev/null || echo "" )
2025-10-22 06:25:26 -07:00
2026-01-06 19:27:04 +01:00
if [ [ $gpu_count -eq 0 ] ] ; then
if [ [ " $cpu_vendor " = = "AuthenticAMD" ] ] ; then
GPU_LIST += ( "integrated" )
GPU_TYPES += ( "AMD_APU" )
GPU_NAMES += ( "AMD APU (Integrated Graphics)" )
2026-01-06 20:32:15 +01:00
( ( gpu_count++) ) || true
2026-01-06 19:27:04 +01:00
else
msg_warn "No GPU detected - skipping hardware acceleration setup"
return 0
fi
fi
# ═══════════════════════════════════════════════════════════════════════════
# GPU Selection - Let user choose which GPU(s) to configure
# ═══════════════════════════════════════════════════════════════════════════
local -a SELECTED_INDICES = ( )
2026-01-27 23:40:47 +02:00
local install_nvidia_drivers = "yes"
2026-01-06 19:27:04 +01:00
if [ [ $gpu_count -eq 1 ] ] ; then
# Single GPU - auto-select
SELECTED_INDICES = ( 0)
msg_ok " Detected GPU: ${ GPU_NAMES [0] } ( ${ GPU_TYPES [0] } ) "
else
# Multiple GPUs - show selection menu
echo ""
2026-01-18 12:43:58 +01:00
msg_custom "⚠" " ${ YW } " "Multiple GPUs detected:"
2026-01-06 19:27:04 +01:00
echo ""
for i in " ${ !GPU_LIST[@] } " ; do
local type_display = " ${ GPU_TYPES [ $i ] } "
case " ${ GPU_TYPES [ $i ] } " in
INTEL_ARC) type_display = "Intel Arc" ; ;
INTEL_GEN9+) type_display = "Intel Gen9+" ; ;
INTEL_LEGACY) type_display = "Intel Legacy" ; ;
INTEL) type_display = "Intel" ; ;
AMD) type_display = "AMD" ; ;
AMD_APU) type_display = "AMD APU" ; ;
NVIDIA) type_display = "NVIDIA" ; ;
esac
printf " %d) [%s] %s\n" " $(( i + 1 )) " " $type_display " " ${ GPU_NAMES [ $i ] } "
done
printf " A) Configure ALL GPUs\n"
echo ""
# Read with 60 second timeout
local selection = ""
echo -n " Select GPU(s) to configure (1- ${ gpu_count } , A=all) [timeout 60s, default=all]: "
if read -r -t 60 selection; then
selection = " ${ selection ^^ } " # uppercase
else
echo ""
msg_info "Timeout - configuring all GPUs automatically"
selection = "A"
fi
# Parse selection
if [ [ " $selection " = = "A" || -z " $selection " ] ] ; then
# Select all
for i in " ${ !GPU_LIST[@] } " ; do
SELECTED_INDICES += ( " $i " )
done
elif [ [ " $selection " = ~ ^[ 0-9,] +$ ] ] ; then
# Parse comma-separated numbers
IFS = ',' read -ra nums <<< " $selection "
for num in " ${ nums [@] } " ; do
num = $( echo " $num " | tr -d ' ' )
if [ [ " $num " = ~ ^[ 0-9] +$ ] ] && ( ( num >= 1 && num <= gpu_count) ) ; then
SELECTED_INDICES += ( " $(( num - 1 )) " )
fi
done
else
# Invalid - default to all
msg_warn "Invalid selection - configuring all GPUs"
for i in " ${ !GPU_LIST[@] } " ; do
SELECTED_INDICES += ( " $i " )
done
fi
2025-10-22 06:25:26 -07:00
fi
2026-01-27 23:40:47 +02:00
# Ask whether to install NVIDIA drivers in the container
local nvidia_selected = "no"
for idx in " ${ SELECTED_INDICES [@] } " ; do
if [ [ " ${ GPU_TYPES [ $idx ] } " = = "NVIDIA" ] ] ; then
nvidia_selected = "yes"
break
fi
done
if [ [ " $nvidia_selected " = = "yes" ] ] ; then
if [ [ -n " ${ INSTALL_NVIDIA_DRIVERS :- } " ] ] ; then
install_nvidia_drivers = " ${ INSTALL_NVIDIA_DRIVERS } "
else
echo ""
msg_custom "🎮" " ${ GN } " "NVIDIA GPU passthrough detected"
local nvidia_reply = ""
read -r -t 60 -p " ${ TAB3 } ⚙️ Install NVIDIA driver libraries in the container? [Y/n] (auto-yes in 60s): " nvidia_reply || nvidia_reply = ""
case " ${ nvidia_reply ,, } " in
n | no) install_nvidia_drivers = "no" ; ;
*) install_nvidia_drivers = "yes" ; ;
esac
fi
fi
2026-01-06 19:27:04 +01:00
# ═══════════════════════════════════════════════════════════════════════════
# OS Detection
# ═══════════════════════════════════════════════════════════════════════════
use setup_hwaccel for robust hardware acceleration (#10054)
* fix(jellyfin): use setup_hwaccel for robust hardware acceleration
Replaces manual hardware acceleration setup with the centralized
setup_hwaccel function from tools.func.
This fixes the installation failure in privileged containers where
/dev/dri does not exist (e.g., when no GPU is passed through).
The setup_hwaccel function includes:
- Proper error handling for missing /dev/dri
- GPU vendor detection (Intel, AMD, NVIDIA)
- Graceful fallback when no GPU is available
Fixes: Installation fails with 'chgrp: cannot access /dev/dri'
when creating privileged containers without GPU passthrough.
* refactor(hwaccel): standardize hardware acceleration across all install scripts
Migrated all install scripts to use the centralized setup_hwaccel function:
- plex-install.sh
- emby-install.sh
- ersatztv-install.sh
- frigate-install.sh
- tdarr-install.sh
- unmanic-install.sh
- channels-install.sh
- ollama-install.sh
- immich-install.sh (added error handling)
Enhanced setup_hwaccel function in tools.func:
- Added -d /dev/dri check before setting permissions
- Added error handling (2>/dev/null || true) for all /dev/dri operations
- Added adduser error handling for video/render groups
- No longer fails if no GPU is detected (graceful skip)
- Added intel-media-va-driver for newer Intel GPUs
- Improved AMD APU support with firmware packages
- Better NVIDIA handling (warning instead of failure)
This fixes installation failures in privileged containers without GPU
passthrough, where /dev/dri does not exist.
Supports: Ubuntu, Debian 12 (Bookworm), Debian 13 (Trixie)
GPU Support: Intel, AMD, NVIDIA (manual driver)
* refactor(hwaccel): complete migration for all GPU apps
Migrated remaining GPU apps to setup_hwaccel:
- fileflows-install.sh
- openwebui-install.sh (added setup_hwaccel - was missing)
- tunarr-install.sh
Also fixed tools/pve/hw-acceleration.sh:
- Added error handling for /dev/dri operations
- Added chmod 660 /dev/dri/* that was missing
- Added error suppression for adduser commands
All 13 GPU apps (var_gpu=yes) now use centralized setup_hwaccel:
jellyfin, plex, emby, ersatztv, frigate, tdarr, unmanic,
channels, ollama, immich, fileflows, openwebui, tunarr
* feat(hwaccel): complete Intel non-free driver support and GID sync
Enhanced setup_hwaccel function:
- Auto-detect Intel GPU generation (Gen 9+ for non-free drivers)
- Debian 12 (Bookworm): Add non-free repo + intel-media-va-driver-non-free
- Debian 13 (Trixie): Add non-free repo + libvpl2 + mesa-opencl-icd
- Ubuntu: Use ubuntu repos with intel-media-va-driver
- Fallback to open drivers if non-free fails
- GID sync for video/render groups (moved from install scripts)
OpenWebUI: Added Intel oneAPI support when installing Ollama
- Intel Level Zero GPU support
- Intel oneAPI Base Toolkit
- Same setup as standalone Ollama install
Cleanup:
- Removed duplicate GID sync from tdarr-install.sh
- Removed duplicate GID sync from unmanic-install.sh
* fix(ersatztv): remove duplicate HW acceleration code
Removed manual Intel HW acceleration setup that remained after
setup_hwaccel migration. The non-free driver prompt is no longer
needed as setup_hwaccel auto-detects Intel GPU generation.
2025-12-17 14:37:31 +01:00
local os_id os_codename os_version
os_id = $( grep -oP '(?<=^ID=).+' /etc/os-release 2>/dev/null | tr -d '"' || echo "debian" )
os_codename = $( grep -oP '(?<=^VERSION_CODENAME=).+' /etc/os-release 2>/dev/null | tr -d '"' || echo "unknown" )
os_version = $( grep -oP '(?<=^VERSION_ID=).+' /etc/os-release 2>/dev/null | tr -d '"' || echo "" )
[ [ -z " $os_id " ] ] && os_id = "debian"
2025-10-22 06:25:26 -07:00
local in_ct = " ${ CTTYPE :- 0 } "
2026-01-06 19:27:04 +01:00
# ═══════════════════════════════════════════════════════════════════════════
# Process Selected GPUs
# ═══════════════════════════════════════════════════════════════════════════
for idx in " ${ SELECTED_INDICES [@] } " ; do
local gpu_type = " ${ GPU_TYPES [ $idx ] } "
local gpu_name = " ${ GPU_NAMES [ $idx ] } "
msg_info " Configuring: ${ gpu_name } "
case " $gpu_type " in
# ─────────────────────────────────────────────────────────────────────────
# Intel Arc GPUs (DG1, DG2, Arc A-series)
# ─────────────────────────────────────────────────────────────────────────
INTEL_ARC)
_setup_intel_arc " $os_id " " $os_codename "
; ;
# ─────────────────────────────────────────────────────────────────────────
# Intel Gen 9+ (Skylake 2015+: UHD, Iris, HD 6xx+)
# ─────────────────────────────────────────────────────────────────────────
INTEL_GEN9+ | INTEL)
_setup_intel_modern " $os_id " " $os_codename "
; ;
# ─────────────────────────────────────────────────────────────────────────
# Intel Legacy (Gen 6-8: HD 2000-5999, Sandy Bridge to Broadwell)
# ─────────────────────────────────────────────────────────────────────────
INTEL_LEGACY)
_setup_intel_legacy " $os_id " " $os_codename "
; ;
# ─────────────────────────────────────────────────────────────────────────
# AMD Discrete GPUs
# ─────────────────────────────────────────────────────────────────────────
AMD)
_setup_amd_gpu " $os_id " " $os_codename "
; ;
# ─────────────────────────────────────────────────────────────────────────
# AMD APU (Integrated Graphics)
# ─────────────────────────────────────────────────────────────────────────
AMD_APU)
_setup_amd_apu " $os_id " " $os_codename "
; ;
# ─────────────────────────────────────────────────────────────────────────
# NVIDIA GPUs
# ─────────────────────────────────────────────────────────────────────────
NVIDIA)
2026-01-27 23:40:47 +02:00
if [ [ " $install_nvidia_drivers " = = "yes" ] ] ; then
_setup_nvidia_gpu " $os_id " " $os_codename " " $os_version "
else
msg_warn "Skipping NVIDIA driver installation (user opted to install manually)"
fi
2026-01-06 19:27:04 +01:00
; ;
esac
done
# ═══════════════════════════════════════════════════════════════════════════
# Device Permissions
# ═══════════════════════════════════════════════════════════════════════════
_setup_gpu_permissions " $in_ct "
cache_installed_version "hwaccel" "1.0"
msg_ok "Setup Hardware Acceleration"
}
# ══════════════════════════════════════════════════════════════════════════════
# Intel Arc GPU Setup
# ══════════════════════════════════════════════════════════════════════════════
_setup_intel_arc( ) {
local os_id = " $1 " os_codename = " $2 "
msg_info "Installing Intel Arc GPU drivers"
if [ [ " $os_id " = = "ubuntu" ] ] ; then
# Ubuntu 22.04+ has Arc support in HWE kernel
$STD apt -y install \
intel-media-va-driver-non-free \
intel-opencl-icd \
2026-02-09 11:04:22 +01:00
libmfx-gen1.2 \
2026-01-06 19:27:04 +01:00
vainfo \
intel-gpu-tools 2>/dev/null || msg_warn "Some Intel Arc packages failed"
elif [ [ " $os_id " = = "debian" ] ] ; then
# Add non-free repos
_add_debian_nonfree " $os_codename "
2026-02-23 13:08:39 +01:00
# For Trixie/Sid: Fetch latest drivers from GitHub (Debian repo packages may be too old or missing)
# For Bookworm: Use repo packages (GitHub latest requires libstdc++6 >= 13.1, unavailable on Bookworm)
if [ [ " $os_codename " = = "trixie" || " $os_codename " = = "sid" ] ] ; then
msg_info "Fetching Intel compute-runtime from GitHub for Arc support"
2026-01-06 19:27:04 +01:00
2026-02-23 13:08:39 +01:00
# libigdgmm - bundled in compute-runtime releases
fetch_and_deploy_gh_release "libigdgmm12" "intel/compute-runtime" "binary" "latest" "" "libigdgmm12_*_amd64.deb" || true
2026-01-06 20:43:07 +01:00
2026-02-23 13:08:39 +01:00
# Intel Graphics Compiler (note: packages have -2 suffix)
fetch_and_deploy_gh_release "intel-igc-core" "intel/intel-graphics-compiler" "binary" "latest" "" "intel-igc-core-2_*_amd64.deb" || true
fetch_and_deploy_gh_release "intel-igc-opencl" "intel/intel-graphics-compiler" "binary" "latest" "" "intel-igc-opencl-2_*_amd64.deb" || true
2026-01-06 20:43:07 +01:00
2026-02-23 13:08:39 +01:00
# Compute Runtime (depends on IGC and gmmlib)
fetch_and_deploy_gh_release "intel-opencl-icd" "intel/compute-runtime" "binary" "latest" "" "intel-opencl-icd_*_amd64.deb" || true
fetch_and_deploy_gh_release "intel-level-zero-gpu" "intel/compute-runtime" "binary" "latest" "" "libze-intel-gpu1_*_amd64.deb" || true
fi
2026-01-06 19:27:04 +01:00
$STD apt -y install \
intel-media-va-driver-non-free \
ocl-icd-libopencl1 \
libvpl2 \
2026-02-09 11:04:22 +01:00
libmfx-gen1.2 \
2026-01-06 19:27:04 +01:00
vainfo \
intel-gpu-tools 2>/dev/null || msg_warn "Some Intel Arc packages failed"
2026-02-23 13:08:39 +01:00
# Bookworm has compatible versions of these packages in repos
[ [ " $os_codename " = = "bookworm" ] ] && $STD apt -y install intel-opencl-icd libigdgmm12 2>/dev/null || true
2026-01-06 19:27:04 +01:00
fi
msg_ok "Intel Arc GPU configured"
}
# ══════════════════════════════════════════════════════════════════════════════
# Intel Modern GPU Setup (Gen 9+)
# ══════════════════════════════════════════════════════════════════════════════
_setup_intel_modern( ) {
local os_id = " $1 " os_codename = " $2 "
msg_info "Installing Intel Gen 9+ GPU drivers"
if [ [ " $os_id " = = "ubuntu" ] ] ; then
$STD apt -y install \
va-driver-all \
intel-media-va-driver \
ocl-icd-libopencl1 \
vainfo \
intel-gpu-tools 2>/dev/null || msg_warn "Some Intel packages failed"
# Try non-free driver for better codec support
$STD apt -y install intel-media-va-driver-non-free 2>/dev/null || true
$STD apt -y install intel-opencl-icd 2>/dev/null || true
$STD apt -y install libmfx-gen1.2 2>/dev/null || true
elif [ [ " $os_id " = = "debian" ] ] ; then
_add_debian_nonfree " $os_codename "
2026-01-06 20:43:07 +01:00
# For Trixie/Sid: Fetch from GitHub (Debian packages too old or missing)
2026-01-06 19:27:04 +01:00
if [ [ " $os_codename " = = "trixie" || " $os_codename " = = "sid" ] ] ; then
2026-01-06 20:43:07 +01:00
msg_info "Fetching Intel compute-runtime from GitHub"
# libigdgmm first (bundled in compute-runtime releases)
fetch_and_deploy_gh_release "libigdgmm12" "intel/compute-runtime" "binary" "latest" "" "libigdgmm12_*_amd64.deb" || true
# Intel Graphics Compiler (note: packages have -2 suffix)
fetch_and_deploy_gh_release "intel-igc-core" "intel/intel-graphics-compiler" "binary" "latest" "" "intel-igc-core-2_*_amd64.deb" || true
fetch_and_deploy_gh_release "intel-igc-opencl" "intel/intel-graphics-compiler" "binary" "latest" "" "intel-igc-opencl-2_*_amd64.deb" || true
# Compute Runtime
2026-01-06 19:27:04 +01:00
fetch_and_deploy_gh_release "intel-opencl-icd" "intel/compute-runtime" "binary" "latest" "" "intel-opencl-icd_*_amd64.deb" || true
fi
$STD apt -y install \
intel-media-va-driver-non-free \
ocl-icd-libopencl1 \
vainfo \
libmfx-gen1.2 \
intel-gpu-tools 2>/dev/null || msg_warn "Some Intel packages failed"
2026-01-06 20:43:07 +01:00
# Bookworm has intel-opencl-icd in repos (compatible version)
[ [ " $os_codename " = = "bookworm" ] ] && $STD apt -y install intel-opencl-icd libigdgmm12 2>/dev/null || true
2026-01-06 19:27:04 +01:00
fi
msg_ok "Intel Gen 9+ GPU configured"
}
# ══════════════════════════════════════════════════════════════════════════════
# Intel Legacy GPU Setup (Gen 6-8)
# ══════════════════════════════════════════════════════════════════════════════
_setup_intel_legacy( ) {
local os_id = " $1 " os_codename = " $2 "
msg_info "Installing Intel Legacy GPU drivers (Gen 6-8)"
# Legacy GPUs use i965 driver - stable repo packages only
$STD apt -y install \
va-driver-all \
i965-va-driver \
mesa-va-drivers \
ocl-icd-libopencl1 \
vainfo \
intel-gpu-tools 2>/dev/null || msg_warn "Some Intel legacy packages failed"
2026-01-10 11:41:44 +01:00
# beignet provides OpenCL for older Intel GPUs (Sandy Bridge to Broadwell)
# Note: beignet-opencl-icd was removed in Debian 12+ and Ubuntu 22.04+
# Check if package is available before attempting installation
if apt-cache show beignet-opencl-icd & >/dev/null; then
$STD apt -y install beignet-opencl-icd 2>/dev/null || msg_warn "beignet-opencl-icd installation failed (optional)"
else
msg_warn "beignet-opencl-icd not available - OpenCL support for legacy Intel GPU limited"
msg_warn "Note: Hardware video encoding/decoding (VA-API) still works without OpenCL"
fi
2026-01-06 19:27:04 +01:00
msg_ok "Intel Legacy GPU configured"
}
# ══════════════════════════════════════════════════════════════════════════════
# AMD Discrete GPU Setup
# ══════════════════════════════════════════════════════════════════════════════
_setup_amd_gpu( ) {
local os_id = " $1 " os_codename = " $2 "
msg_info "Installing AMD GPU drivers"
# Core Mesa drivers
$STD apt -y install \
mesa-va-drivers \
mesa-vdpau-drivers \
mesa-opencl-icd \
ocl-icd-libopencl1 \
libdrm-amdgpu1 \
vainfo \
clinfo 2>/dev/null || msg_warn "Some AMD packages failed"
# Firmware for AMD GPUs
if [ [ " $os_id " = = "debian" ] ] ; then
_add_debian_nonfree_firmware " $os_codename "
$STD apt -y install firmware-amd-graphics 2>/dev/null || msg_warn "AMD firmware not available"
fi
# Ubuntu includes AMD firmware in linux-firmware by default
# ROCm for compute (optional - large download)
# Uncomment if needed:
# $STD apt -y install rocm-opencl-runtime 2>/dev/null || true
msg_ok "AMD GPU configured"
}
# ══════════════════════════════════════════════════════════════════════════════
# AMD APU Setup (Integrated Graphics)
# ══════════════════════════════════════════════════════════════════════════════
_setup_amd_apu( ) {
local os_id = " $1 " os_codename = " $2 "
msg_info "Installing AMD APU drivers"
$STD apt -y install \
mesa-va-drivers \
mesa-vdpau-drivers \
mesa-opencl-icd \
ocl-icd-libopencl1 \
vainfo 2>/dev/null || msg_warn "Some AMD APU packages failed"
if [ [ " $os_id " = = "debian" ] ] ; then
_add_debian_nonfree_firmware " $os_codename "
$STD apt -y install firmware-amd-graphics 2>/dev/null || true
fi
msg_ok "AMD APU configured"
}
# ══════════════════════════════════════════════════════════════════════════════
# NVIDIA GPU Setup
# ══════════════════════════════════════════════════════════════════════════════
_setup_nvidia_gpu( ) {
local os_id = " $1 " os_codename = " $2 " os_version = " $3 "
msg_info "Installing NVIDIA GPU drivers"
2026-01-14 15:51:00 +01:00
# Prevent interactive dialogs (e.g., "Mismatching nvidia kernel module" whiptail)
export DEBIAN_FRONTEND = noninteractive
export NEEDRESTART_MODE = a
2026-01-06 19:27:04 +01:00
# Detect host driver version (passed through via /proc)
2026-01-14 14:39:53 +01:00
# Format varies by driver type:
# Proprietary: "NVRM version: NVIDIA UNIX x86_64 Kernel Module 550.54.14 Thu..."
# Open: "NVRM version: NVIDIA UNIX Open Kernel Module for x86_64 590.48.01 Release..."
# Use regex to extract version number (###.##.## pattern)
2026-01-06 19:27:04 +01:00
local nvidia_host_version = ""
if [ [ -f /proc/driver/nvidia/version ] ] ; then
2026-01-14 14:39:53 +01:00
nvidia_host_version = $( grep -oP '\d{3,}\.\d+\.\d+' /proc/driver/nvidia/version 2>/dev/null | head -1)
2026-01-06 19:27:04 +01:00
fi
if [ [ -z " $nvidia_host_version " ] ] ; then
msg_warn "NVIDIA host driver version not found in /proc/driver/nvidia/version"
msg_warn "Ensure NVIDIA drivers are installed on host and GPU passthrough is enabled"
2026-01-14 15:51:00 +01:00
$STD apt-get -y install va-driver-all vainfo 2>/dev/null || true
2026-01-06 19:27:04 +01:00
return 0
fi
msg_info " Host NVIDIA driver version: ${ nvidia_host_version } "
if [ [ " $os_id " = = "debian" ] ] ; then
# Enable non-free components
if [ [ -f /etc/apt/sources.list.d/debian.sources ] ] ; then
if ! grep -q "non-free" /etc/apt/sources.list.d/debian.sources 2>/dev/null; then
sed -i -E 's/Components: (.*)$/Components: \1 contrib non-free non-free-firmware/g' /etc/apt/sources.list.d/debian.sources 2>/dev/null || true
fi
fi
2026-01-14 15:51:00 +01:00
$STD apt-get -y update 2>/dev/null || msg_warn "apt update failed - continuing anyway"
2026-01-06 19:27:04 +01:00
2026-01-14 14:39:53 +01:00
# For Debian 13 Trixie/Sid: Use Debian's own nvidia packages first (better compatibility)
# NVIDIA's CUDA repo targets Debian 12 and may not have amd64 packages for Trixie
if [ [ " $os_codename " = = "trixie" || " $os_codename " = = "sid" ] ] ; then
msg_info " Debian ${ os_codename } : Using Debian's NVIDIA packages "
2026-01-06 19:27:04 +01:00
2026-01-18 12:43:58 +01:00
# Extract major version for flexible matching (580.126.09 -> 580)
local nvidia_major_version = " ${ nvidia_host_version %%.* } "
# Check what versions are actually available
local available_version = ""
available_version = $( apt-cache madison libcuda1 2>/dev/null | awk '{print $3}' | grep -E " ^ ${ nvidia_major_version } \. " | head -1 || true )
if [ [ -n " $available_version " ] ] ; then
msg_info " Found available NVIDIA version: ${ available_version } "
local nvidia_pkgs = " libcuda1= ${ available_version } libnvcuvid1= ${ available_version } libnvidia-encode1= ${ available_version } libnvidia-ml1= ${ available_version } "
if $STD apt-get -y -o Dpkg::Options::= "--force-confold" install --no-install-recommends $nvidia_pkgs 2>/dev/null; then
msg_ok " Installed NVIDIA libraries ( ${ available_version } ) "
else
msg_warn " Failed to install NVIDIA ${ available_version } - trying unversioned "
$STD apt-get -y -o Dpkg::Options::= "--force-confold" install --no-install-recommends libcuda1 libnvcuvid1 libnvidia-encode1 libnvidia-ml1 2>/dev/null || true
fi
2026-01-06 19:27:04 +01:00
else
2026-01-18 12:43:58 +01:00
# No matching major version - try latest available or unversioned
msg_warn " No NVIDIA packages for version ${ nvidia_major_version } .x found in repos "
available_version = $( apt-cache madison libcuda1 2>/dev/null | awk '{print $3}' | head -1 || true )
if [ [ -n " $available_version " ] ] ; then
msg_info " Trying latest available: ${ available_version } (may cause version mismatch) "
$STD apt-get -y -o Dpkg::Options::= "--force-confold" install --no-install-recommends \
libcuda1 = " ${ available_version } " libnvcuvid1 = " ${ available_version } " \
libnvidia-encode1= " ${ available_version } " libnvidia-ml1= " ${ available_version } " 2>/dev/null ||
$STD apt-get -y -o Dpkg::Options::= "--force-confold" install --no-install-recommends \
libcuda1 libnvcuvid1 libnvidia-encode1 libnvidia-ml1 2>/dev/null ||
msg_warn "NVIDIA library installation failed - GPU compute may not work"
2026-01-14 14:39:53 +01:00
else
2026-01-18 12:43:58 +01:00
msg_warn "No NVIDIA packages available in Debian repos - GPU support disabled"
2026-01-14 14:39:53 +01:00
fi
2026-01-06 19:27:04 +01:00
fi
2026-01-14 15:51:00 +01:00
$STD apt-get -y -o Dpkg::Options::= "--force-confold" install --no-install-recommends nvidia-smi 2>/dev/null || true
2026-01-14 14:39:53 +01:00
else
# Debian 11/12: Use NVIDIA CUDA repository for version matching
local cuda_repo = "debian12"
case " $os_codename " in
bullseye) cuda_repo = "debian11" ; ;
bookworm) cuda_repo = "debian12" ; ;
esac
2026-01-06 19:27:04 +01:00
2026-01-14 14:39:53 +01:00
# Add NVIDIA CUDA repository
if [ [ ! -f /usr/share/keyrings/cuda-archive-keyring.gpg ] ] ; then
msg_info " Adding NVIDIA CUDA repository ( ${ cuda_repo } ) "
local cuda_keyring
cuda_keyring = " $( mktemp) "
if curl -fsSL -o " $cuda_keyring " " https://developer.download.nvidia.com/compute/cuda/repos/ ${ cuda_repo } /x86_64/cuda-keyring_1.1-1_all.deb " 2>/dev/null; then
$STD dpkg -i " $cuda_keyring " 2>/dev/null || true
else
msg_warn "Failed to download NVIDIA CUDA keyring"
fi
rm -f " $cuda_keyring "
fi
# Pin NVIDIA repo for version matching
cat <<'NVIDIA_PIN ' >/etc/apt/preferences.d/nvidia-cuda-pin
2026-01-06 19:27:04 +01:00
Package: *
Pin: origin developer.download.nvidia.com
Pin-Priority: 1001
NVIDIA_PIN
2026-01-14 15:51:00 +01:00
$STD apt-get -y update 2>/dev/null || msg_warn "apt update failed - continuing anyway"
2026-01-06 19:27:04 +01:00
2026-01-18 12:43:58 +01:00
# Extract major version for flexible matching (580.126.09 -> 580)
local nvidia_major_version = " ${ nvidia_host_version %%.* } "
2026-01-06 19:27:04 +01:00
2026-01-18 12:43:58 +01:00
# Check what versions are actually available in CUDA repo
local available_version = ""
available_version = $( apt-cache madison libcuda1 2>/dev/null | awk '{print $3}' | grep -E " ^ ${ nvidia_major_version } \. " | head -1 || true )
if [ [ -n " $available_version " ] ] ; then
msg_info " Installing NVIDIA libraries (version ${ available_version } ) "
local nvidia_pkgs = " libcuda1= ${ available_version } libnvcuvid1= ${ available_version } libnvidia-encode1= ${ available_version } libnvidia-ml1= ${ available_version } "
if $STD apt-get -y -o Dpkg::Options::= "--force-confold" install --no-install-recommends $nvidia_pkgs 2>/dev/null; then
msg_ok "Installed version-matched NVIDIA libraries"
else
msg_warn "Version-pinned install failed - trying unpinned"
$STD apt-get -y -o Dpkg::Options::= "--force-confold" install --no-install-recommends libcuda1 libnvcuvid1 libnvidia-encode1 libnvidia-ml1 2>/dev/null ||
msg_warn "NVIDIA library installation failed"
fi
2026-01-06 19:27:04 +01:00
else
2026-01-18 12:43:58 +01:00
msg_warn " No NVIDIA packages for version ${ nvidia_major_version } .x in CUDA repo (host: ${ nvidia_host_version } ) "
# Try latest available version
available_version = $( apt-cache madison libcuda1 2>/dev/null | awk '{print $3}' | head -1 || true )
if [ [ -n " $available_version " ] ] ; then
msg_info " Trying latest available: ${ available_version } (version mismatch warning) "
if $STD apt-get -y -o Dpkg::Options::= "--force-confold" install --no-install-recommends \
libcuda1 = " ${ available_version } " libnvcuvid1 = " ${ available_version } " \
libnvidia-encode1= " ${ available_version } " libnvidia-ml1= " ${ available_version } " 2>/dev/null; then
msg_ok " Installed NVIDIA libraries ( ${ available_version } ) - version differs from host "
else
$STD apt-get -y -o Dpkg::Options::= "--force-confold" install --no-install-recommends libcuda1 libnvcuvid1 libnvidia-encode1 libnvidia-ml1 2>/dev/null ||
msg_warn "NVIDIA library installation failed"
fi
2026-01-14 14:39:53 +01:00
else
2026-01-18 12:43:58 +01:00
msg_warn "No NVIDIA packages available in CUDA repo - GPU support disabled"
2026-01-14 14:39:53 +01:00
fi
2026-01-05 18:03:02 +01:00
fi
2026-01-14 15:51:00 +01:00
$STD apt-get -y -o Dpkg::Options::= "--force-confold" install --no-install-recommends nvidia-smi 2>/dev/null || true
2026-01-14 14:39:53 +01:00
fi
2026-01-06 19:27:04 +01:00
elif [ [ " $os_id " = = "ubuntu" ] ] ; then
# Ubuntu versioning
local ubuntu_cuda_repo = ""
case " $os_version " in
22.04) ubuntu_cuda_repo = "ubuntu2204" ; ;
24.04) ubuntu_cuda_repo = "ubuntu2404" ; ;
*) ubuntu_cuda_repo = "ubuntu2204" ; ; # Fallback
esac
# Add NVIDIA CUDA repository for Ubuntu
if [ [ ! -f /usr/share/keyrings/cuda-archive-keyring.gpg ] ] ; then
msg_info " Adding NVIDIA CUDA repository ( ${ ubuntu_cuda_repo } ) "
local cuda_keyring
cuda_keyring = " $( mktemp) "
if curl -fsSL -o " $cuda_keyring " " https://developer.download.nvidia.com/compute/cuda/repos/ ${ ubuntu_cuda_repo } /x86_64/cuda-keyring_1.1-1_all.deb " 2>/dev/null; then
$STD dpkg -i " $cuda_keyring " 2>/dev/null || true
else
msg_warn "Failed to download NVIDIA CUDA keyring"
fi
rm -f " $cuda_keyring "
fi
2026-01-14 15:51:00 +01:00
$STD apt-get -y update 2>/dev/null || msg_warn "apt update failed - continuing anyway"
2026-01-06 19:27:04 +01:00
2026-01-18 12:43:58 +01:00
# Extract major version for flexible matching
local nvidia_major_version = " ${ nvidia_host_version %%.* } "
# Check what versions are available
local available_version = ""
available_version = $( apt-cache madison libcuda1 2>/dev/null | awk '{print $3}' | grep -E " ^ ${ nvidia_major_version } \. " | head -1 || true )
if [ [ -n " $available_version " ] ] ; then
msg_info " Installing NVIDIA libraries (version ${ available_version } ) "
local nvidia_pkgs = " libcuda1= ${ available_version } libnvcuvid1= ${ available_version } libnvidia-encode1= ${ available_version } libnvidia-ml1= ${ available_version } "
if $STD apt-get -y -o Dpkg::Options::= "--force-confold" install --no-install-recommends $nvidia_pkgs 2>/dev/null; then
msg_ok "Installed version-matched NVIDIA libraries"
else
2026-01-24 23:23:10 +01:00
# Fallback to Ubuntu repo packages with versioned nvidia-utils
msg_warn " CUDA repo install failed - trying Ubuntu native packages (nvidia-utils- ${ nvidia_major_version } ) "
if $STD apt-get -y -o Dpkg::Options::= "--force-confold" install --no-install-recommends \
libnvidia-decode-${ nvidia_major_version } libnvidia-encode-${ nvidia_major_version } nvidia-utils-${ nvidia_major_version } 2>/dev/null; then
msg_ok " Installed Ubuntu NVIDIA packages ( ${ nvidia_major_version } ) "
else
msg_warn " NVIDIA driver installation failed - please install manually: apt install nvidia-utils- ${ nvidia_major_version } "
fi
2026-01-18 12:43:58 +01:00
fi
2026-01-06 19:27:04 +01:00
else
2026-01-18 12:43:58 +01:00
msg_warn " No NVIDIA packages for version ${ nvidia_major_version } .x in CUDA repo "
2026-01-24 23:23:10 +01:00
# Fallback to Ubuntu repo packages with versioned nvidia-utils
msg_info " Trying Ubuntu native packages (nvidia-utils- ${ nvidia_major_version } ) "
if $STD apt-get -y -o Dpkg::Options::= "--force-confold" install --no-install-recommends \
libnvidia-decode-${ nvidia_major_version } libnvidia-encode-${ nvidia_major_version } nvidia-utils-${ nvidia_major_version } 2>/dev/null; then
msg_ok " Installed Ubuntu NVIDIA packages ( ${ nvidia_major_version } ) "
else
msg_warn " NVIDIA driver installation failed - please install manually: apt install nvidia-utils- ${ nvidia_major_version } "
fi
2026-01-06 19:27:04 +01:00
fi
fi
# VA-API for hybrid setups (Intel + NVIDIA)
2026-01-14 15:51:00 +01:00
$STD apt-get -y install va-driver-all vainfo 2>/dev/null || true
2026-01-06 19:27:04 +01:00
2026-02-26 22:27:46 +01:00
# Fix GLX alternatives: nvidia-alternative diverts mesa libs but in LXC
# containers the nvidia GLX libs are typically missing, leaving libGL.so.1
# pointing nowhere. Fall back to mesa if nvidia GLX dir is empty/missing.
if command -v update-glx & >/dev/null; then
local nvidia_glx_dir = "/usr/lib/nvidia"
if [ [ ! -f " ${ nvidia_glx_dir } /libGL.so.1 " ] ] && [ [ -d /usr/lib/mesa-diverted ] ] ; then
msg_info "NVIDIA GLX libs missing in container - falling back to mesa"
$STD update-glx --set glx /usr/lib/mesa-diverted 2>/dev/null || true
ldconfig 2>/dev/null || true
fi
fi
2026-01-06 19:27:04 +01:00
msg_ok "NVIDIA GPU configured"
}
# ══════════════════════════════════════════════════════════════════════════════
# Helper: Add Debian non-free repositories
# ══════════════════════════════════════════════════════════════════════════════
_add_debian_nonfree( ) {
local os_codename = " $1 "
2026-01-05 18:03:02 +01:00
2026-01-06 19:27:04 +01:00
[ [ -f /etc/apt/sources.list.d/non-free.sources ] ] && return 0
2026-01-05 18:03:02 +01:00
2026-01-06 19:27:04 +01:00
case " $os_codename " in
bullseye)
cat <<'EOF' >/etc/apt/sources.list.d/non-free.sources
Types: deb
URIs: http://deb.debian.org/debian
Suites: bullseye bullseye-updates
Components: non-free
2026-02-23 12:59:42 +01:00
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg
2026-01-06 19:27:04 +01:00
EOF
; ;
bookworm)
cat <<'EOF' >/etc/apt/sources.list.d/non-free.sources
use setup_hwaccel for robust hardware acceleration (#10054)
* fix(jellyfin): use setup_hwaccel for robust hardware acceleration
Replaces manual hardware acceleration setup with the centralized
setup_hwaccel function from tools.func.
This fixes the installation failure in privileged containers where
/dev/dri does not exist (e.g., when no GPU is passed through).
The setup_hwaccel function includes:
- Proper error handling for missing /dev/dri
- GPU vendor detection (Intel, AMD, NVIDIA)
- Graceful fallback when no GPU is available
Fixes: Installation fails with 'chgrp: cannot access /dev/dri'
when creating privileged containers without GPU passthrough.
* refactor(hwaccel): standardize hardware acceleration across all install scripts
Migrated all install scripts to use the centralized setup_hwaccel function:
- plex-install.sh
- emby-install.sh
- ersatztv-install.sh
- frigate-install.sh
- tdarr-install.sh
- unmanic-install.sh
- channels-install.sh
- ollama-install.sh
- immich-install.sh (added error handling)
Enhanced setup_hwaccel function in tools.func:
- Added -d /dev/dri check before setting permissions
- Added error handling (2>/dev/null || true) for all /dev/dri operations
- Added adduser error handling for video/render groups
- No longer fails if no GPU is detected (graceful skip)
- Added intel-media-va-driver for newer Intel GPUs
- Improved AMD APU support with firmware packages
- Better NVIDIA handling (warning instead of failure)
This fixes installation failures in privileged containers without GPU
passthrough, where /dev/dri does not exist.
Supports: Ubuntu, Debian 12 (Bookworm), Debian 13 (Trixie)
GPU Support: Intel, AMD, NVIDIA (manual driver)
* refactor(hwaccel): complete migration for all GPU apps
Migrated remaining GPU apps to setup_hwaccel:
- fileflows-install.sh
- openwebui-install.sh (added setup_hwaccel - was missing)
- tunarr-install.sh
Also fixed tools/pve/hw-acceleration.sh:
- Added error handling for /dev/dri operations
- Added chmod 660 /dev/dri/* that was missing
- Added error suppression for adduser commands
All 13 GPU apps (var_gpu=yes) now use centralized setup_hwaccel:
jellyfin, plex, emby, ersatztv, frigate, tdarr, unmanic,
channels, ollama, immich, fileflows, openwebui, tunarr
* feat(hwaccel): complete Intel non-free driver support and GID sync
Enhanced setup_hwaccel function:
- Auto-detect Intel GPU generation (Gen 9+ for non-free drivers)
- Debian 12 (Bookworm): Add non-free repo + intel-media-va-driver-non-free
- Debian 13 (Trixie): Add non-free repo + libvpl2 + mesa-opencl-icd
- Ubuntu: Use ubuntu repos with intel-media-va-driver
- Fallback to open drivers if non-free fails
- GID sync for video/render groups (moved from install scripts)
OpenWebUI: Added Intel oneAPI support when installing Ollama
- Intel Level Zero GPU support
- Intel oneAPI Base Toolkit
- Same setup as standalone Ollama install
Cleanup:
- Removed duplicate GID sync from tdarr-install.sh
- Removed duplicate GID sync from unmanic-install.sh
* fix(ersatztv): remove duplicate HW acceleration code
Removed manual Intel HW acceleration setup that remained after
setup_hwaccel migration. The non-free driver prompt is no longer
needed as setup_hwaccel auto-detects Intel GPU generation.
2025-12-17 14:37:31 +01:00
Types: deb
URIs: http://deb.debian.org/debian
Suites: bookworm bookworm-updates
Components: non-free non-free-firmware
2026-02-23 12:59:42 +01:00
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg
use setup_hwaccel for robust hardware acceleration (#10054)
* fix(jellyfin): use setup_hwaccel for robust hardware acceleration
Replaces manual hardware acceleration setup with the centralized
setup_hwaccel function from tools.func.
This fixes the installation failure in privileged containers where
/dev/dri does not exist (e.g., when no GPU is passed through).
The setup_hwaccel function includes:
- Proper error handling for missing /dev/dri
- GPU vendor detection (Intel, AMD, NVIDIA)
- Graceful fallback when no GPU is available
Fixes: Installation fails with 'chgrp: cannot access /dev/dri'
when creating privileged containers without GPU passthrough.
* refactor(hwaccel): standardize hardware acceleration across all install scripts
Migrated all install scripts to use the centralized setup_hwaccel function:
- plex-install.sh
- emby-install.sh
- ersatztv-install.sh
- frigate-install.sh
- tdarr-install.sh
- unmanic-install.sh
- channels-install.sh
- ollama-install.sh
- immich-install.sh (added error handling)
Enhanced setup_hwaccel function in tools.func:
- Added -d /dev/dri check before setting permissions
- Added error handling (2>/dev/null || true) for all /dev/dri operations
- Added adduser error handling for video/render groups
- No longer fails if no GPU is detected (graceful skip)
- Added intel-media-va-driver for newer Intel GPUs
- Improved AMD APU support with firmware packages
- Better NVIDIA handling (warning instead of failure)
This fixes installation failures in privileged containers without GPU
passthrough, where /dev/dri does not exist.
Supports: Ubuntu, Debian 12 (Bookworm), Debian 13 (Trixie)
GPU Support: Intel, AMD, NVIDIA (manual driver)
* refactor(hwaccel): complete migration for all GPU apps
Migrated remaining GPU apps to setup_hwaccel:
- fileflows-install.sh
- openwebui-install.sh (added setup_hwaccel - was missing)
- tunarr-install.sh
Also fixed tools/pve/hw-acceleration.sh:
- Added error handling for /dev/dri operations
- Added chmod 660 /dev/dri/* that was missing
- Added error suppression for adduser commands
All 13 GPU apps (var_gpu=yes) now use centralized setup_hwaccel:
jellyfin, plex, emby, ersatztv, frigate, tdarr, unmanic,
channels, ollama, immich, fileflows, openwebui, tunarr
* feat(hwaccel): complete Intel non-free driver support and GID sync
Enhanced setup_hwaccel function:
- Auto-detect Intel GPU generation (Gen 9+ for non-free drivers)
- Debian 12 (Bookworm): Add non-free repo + intel-media-va-driver-non-free
- Debian 13 (Trixie): Add non-free repo + libvpl2 + mesa-opencl-icd
- Ubuntu: Use ubuntu repos with intel-media-va-driver
- Fallback to open drivers if non-free fails
- GID sync for video/render groups (moved from install scripts)
OpenWebUI: Added Intel oneAPI support when installing Ollama
- Intel Level Zero GPU support
- Intel oneAPI Base Toolkit
- Same setup as standalone Ollama install
Cleanup:
- Removed duplicate GID sync from tdarr-install.sh
- Removed duplicate GID sync from unmanic-install.sh
* fix(ersatztv): remove duplicate HW acceleration code
Removed manual Intel HW acceleration setup that remained after
setup_hwaccel migration. The non-free driver prompt is no longer
needed as setup_hwaccel auto-detects Intel GPU generation.
2025-12-17 14:37:31 +01:00
EOF
2026-01-06 19:27:04 +01:00
; ;
trixie | sid)
cat <<'EOF' >/etc/apt/sources.list.d/non-free.sources
use setup_hwaccel for robust hardware acceleration (#10054)
* fix(jellyfin): use setup_hwaccel for robust hardware acceleration
Replaces manual hardware acceleration setup with the centralized
setup_hwaccel function from tools.func.
This fixes the installation failure in privileged containers where
/dev/dri does not exist (e.g., when no GPU is passed through).
The setup_hwaccel function includes:
- Proper error handling for missing /dev/dri
- GPU vendor detection (Intel, AMD, NVIDIA)
- Graceful fallback when no GPU is available
Fixes: Installation fails with 'chgrp: cannot access /dev/dri'
when creating privileged containers without GPU passthrough.
* refactor(hwaccel): standardize hardware acceleration across all install scripts
Migrated all install scripts to use the centralized setup_hwaccel function:
- plex-install.sh
- emby-install.sh
- ersatztv-install.sh
- frigate-install.sh
- tdarr-install.sh
- unmanic-install.sh
- channels-install.sh
- ollama-install.sh
- immich-install.sh (added error handling)
Enhanced setup_hwaccel function in tools.func:
- Added -d /dev/dri check before setting permissions
- Added error handling (2>/dev/null || true) for all /dev/dri operations
- Added adduser error handling for video/render groups
- No longer fails if no GPU is detected (graceful skip)
- Added intel-media-va-driver for newer Intel GPUs
- Improved AMD APU support with firmware packages
- Better NVIDIA handling (warning instead of failure)
This fixes installation failures in privileged containers without GPU
passthrough, where /dev/dri does not exist.
Supports: Ubuntu, Debian 12 (Bookworm), Debian 13 (Trixie)
GPU Support: Intel, AMD, NVIDIA (manual driver)
* refactor(hwaccel): complete migration for all GPU apps
Migrated remaining GPU apps to setup_hwaccel:
- fileflows-install.sh
- openwebui-install.sh (added setup_hwaccel - was missing)
- tunarr-install.sh
Also fixed tools/pve/hw-acceleration.sh:
- Added error handling for /dev/dri operations
- Added chmod 660 /dev/dri/* that was missing
- Added error suppression for adduser commands
All 13 GPU apps (var_gpu=yes) now use centralized setup_hwaccel:
jellyfin, plex, emby, ersatztv, frigate, tdarr, unmanic,
channels, ollama, immich, fileflows, openwebui, tunarr
* feat(hwaccel): complete Intel non-free driver support and GID sync
Enhanced setup_hwaccel function:
- Auto-detect Intel GPU generation (Gen 9+ for non-free drivers)
- Debian 12 (Bookworm): Add non-free repo + intel-media-va-driver-non-free
- Debian 13 (Trixie): Add non-free repo + libvpl2 + mesa-opencl-icd
- Ubuntu: Use ubuntu repos with intel-media-va-driver
- Fallback to open drivers if non-free fails
- GID sync for video/render groups (moved from install scripts)
OpenWebUI: Added Intel oneAPI support when installing Ollama
- Intel Level Zero GPU support
- Intel oneAPI Base Toolkit
- Same setup as standalone Ollama install
Cleanup:
- Removed duplicate GID sync from tdarr-install.sh
- Removed duplicate GID sync from unmanic-install.sh
* fix(ersatztv): remove duplicate HW acceleration code
Removed manual Intel HW acceleration setup that remained after
setup_hwaccel migration. The non-free driver prompt is no longer
needed as setup_hwaccel auto-detects Intel GPU generation.
2025-12-17 14:37:31 +01:00
Types: deb
URIs: http://deb.debian.org/debian
Suites: trixie trixie-updates
Components: non-free non-free-firmware
2026-02-23 12:59:42 +01:00
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg
2025-10-22 06:25:26 -07:00
use setup_hwaccel for robust hardware acceleration (#10054)
* fix(jellyfin): use setup_hwaccel for robust hardware acceleration
Replaces manual hardware acceleration setup with the centralized
setup_hwaccel function from tools.func.
This fixes the installation failure in privileged containers where
/dev/dri does not exist (e.g., when no GPU is passed through).
The setup_hwaccel function includes:
- Proper error handling for missing /dev/dri
- GPU vendor detection (Intel, AMD, NVIDIA)
- Graceful fallback when no GPU is available
Fixes: Installation fails with 'chgrp: cannot access /dev/dri'
when creating privileged containers without GPU passthrough.
* refactor(hwaccel): standardize hardware acceleration across all install scripts
Migrated all install scripts to use the centralized setup_hwaccel function:
- plex-install.sh
- emby-install.sh
- ersatztv-install.sh
- frigate-install.sh
- tdarr-install.sh
- unmanic-install.sh
- channels-install.sh
- ollama-install.sh
- immich-install.sh (added error handling)
Enhanced setup_hwaccel function in tools.func:
- Added -d /dev/dri check before setting permissions
- Added error handling (2>/dev/null || true) for all /dev/dri operations
- Added adduser error handling for video/render groups
- No longer fails if no GPU is detected (graceful skip)
- Added intel-media-va-driver for newer Intel GPUs
- Improved AMD APU support with firmware packages
- Better NVIDIA handling (warning instead of failure)
This fixes installation failures in privileged containers without GPU
passthrough, where /dev/dri does not exist.
Supports: Ubuntu, Debian 12 (Bookworm), Debian 13 (Trixie)
GPU Support: Intel, AMD, NVIDIA (manual driver)
* refactor(hwaccel): complete migration for all GPU apps
Migrated remaining GPU apps to setup_hwaccel:
- fileflows-install.sh
- openwebui-install.sh (added setup_hwaccel - was missing)
- tunarr-install.sh
Also fixed tools/pve/hw-acceleration.sh:
- Added error handling for /dev/dri operations
- Added chmod 660 /dev/dri/* that was missing
- Added error suppression for adduser commands
All 13 GPU apps (var_gpu=yes) now use centralized setup_hwaccel:
jellyfin, plex, emby, ersatztv, frigate, tdarr, unmanic,
channels, ollama, immich, fileflows, openwebui, tunarr
* feat(hwaccel): complete Intel non-free driver support and GID sync
Enhanced setup_hwaccel function:
- Auto-detect Intel GPU generation (Gen 9+ for non-free drivers)
- Debian 12 (Bookworm): Add non-free repo + intel-media-va-driver-non-free
- Debian 13 (Trixie): Add non-free repo + libvpl2 + mesa-opencl-icd
- Ubuntu: Use ubuntu repos with intel-media-va-driver
- Fallback to open drivers if non-free fails
- GID sync for video/render groups (moved from install scripts)
OpenWebUI: Added Intel oneAPI support when installing Ollama
- Intel Level Zero GPU support
- Intel oneAPI Base Toolkit
- Same setup as standalone Ollama install
Cleanup:
- Removed duplicate GID sync from tdarr-install.sh
- Removed duplicate GID sync from unmanic-install.sh
* fix(ersatztv): remove duplicate HW acceleration code
Removed manual Intel HW acceleration setup that remained after
setup_hwaccel migration. The non-free driver prompt is no longer
needed as setup_hwaccel auto-detects Intel GPU generation.
2025-12-17 14:37:31 +01:00
Types: deb
URIs: http://deb.debian.org/debian-security
Suites: trixie-security
Components: non-free non-free-firmware
2026-02-23 12:59:42 +01:00
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg
use setup_hwaccel for robust hardware acceleration (#10054)
* fix(jellyfin): use setup_hwaccel for robust hardware acceleration
Replaces manual hardware acceleration setup with the centralized
setup_hwaccel function from tools.func.
This fixes the installation failure in privileged containers where
/dev/dri does not exist (e.g., when no GPU is passed through).
The setup_hwaccel function includes:
- Proper error handling for missing /dev/dri
- GPU vendor detection (Intel, AMD, NVIDIA)
- Graceful fallback when no GPU is available
Fixes: Installation fails with 'chgrp: cannot access /dev/dri'
when creating privileged containers without GPU passthrough.
* refactor(hwaccel): standardize hardware acceleration across all install scripts
Migrated all install scripts to use the centralized setup_hwaccel function:
- plex-install.sh
- emby-install.sh
- ersatztv-install.sh
- frigate-install.sh
- tdarr-install.sh
- unmanic-install.sh
- channels-install.sh
- ollama-install.sh
- immich-install.sh (added error handling)
Enhanced setup_hwaccel function in tools.func:
- Added -d /dev/dri check before setting permissions
- Added error handling (2>/dev/null || true) for all /dev/dri operations
- Added adduser error handling for video/render groups
- No longer fails if no GPU is detected (graceful skip)
- Added intel-media-va-driver for newer Intel GPUs
- Improved AMD APU support with firmware packages
- Better NVIDIA handling (warning instead of failure)
This fixes installation failures in privileged containers without GPU
passthrough, where /dev/dri does not exist.
Supports: Ubuntu, Debian 12 (Bookworm), Debian 13 (Trixie)
GPU Support: Intel, AMD, NVIDIA (manual driver)
* refactor(hwaccel): complete migration for all GPU apps
Migrated remaining GPU apps to setup_hwaccel:
- fileflows-install.sh
- openwebui-install.sh (added setup_hwaccel - was missing)
- tunarr-install.sh
Also fixed tools/pve/hw-acceleration.sh:
- Added error handling for /dev/dri operations
- Added chmod 660 /dev/dri/* that was missing
- Added error suppression for adduser commands
All 13 GPU apps (var_gpu=yes) now use centralized setup_hwaccel:
jellyfin, plex, emby, ersatztv, frigate, tdarr, unmanic,
channels, ollama, immich, fileflows, openwebui, tunarr
* feat(hwaccel): complete Intel non-free driver support and GID sync
Enhanced setup_hwaccel function:
- Auto-detect Intel GPU generation (Gen 9+ for non-free drivers)
- Debian 12 (Bookworm): Add non-free repo + intel-media-va-driver-non-free
- Debian 13 (Trixie): Add non-free repo + libvpl2 + mesa-opencl-icd
- Ubuntu: Use ubuntu repos with intel-media-va-driver
- Fallback to open drivers if non-free fails
- GID sync for video/render groups (moved from install scripts)
OpenWebUI: Added Intel oneAPI support when installing Ollama
- Intel Level Zero GPU support
- Intel oneAPI Base Toolkit
- Same setup as standalone Ollama install
Cleanup:
- Removed duplicate GID sync from tdarr-install.sh
- Removed duplicate GID sync from unmanic-install.sh
* fix(ersatztv): remove duplicate HW acceleration code
Removed manual Intel HW acceleration setup that remained after
setup_hwaccel migration. The non-free driver prompt is no longer
needed as setup_hwaccel auto-detects Intel GPU generation.
2025-12-17 14:37:31 +01:00
EOF
2025-10-22 06:25:26 -07:00
; ;
2026-01-06 19:27:04 +01:00
esac
$STD apt -y update
}
use setup_hwaccel for robust hardware acceleration (#10054)
* fix(jellyfin): use setup_hwaccel for robust hardware acceleration
Replaces manual hardware acceleration setup with the centralized
setup_hwaccel function from tools.func.
This fixes the installation failure in privileged containers where
/dev/dri does not exist (e.g., when no GPU is passed through).
The setup_hwaccel function includes:
- Proper error handling for missing /dev/dri
- GPU vendor detection (Intel, AMD, NVIDIA)
- Graceful fallback when no GPU is available
Fixes: Installation fails with 'chgrp: cannot access /dev/dri'
when creating privileged containers without GPU passthrough.
* refactor(hwaccel): standardize hardware acceleration across all install scripts
Migrated all install scripts to use the centralized setup_hwaccel function:
- plex-install.sh
- emby-install.sh
- ersatztv-install.sh
- frigate-install.sh
- tdarr-install.sh
- unmanic-install.sh
- channels-install.sh
- ollama-install.sh
- immich-install.sh (added error handling)
Enhanced setup_hwaccel function in tools.func:
- Added -d /dev/dri check before setting permissions
- Added error handling (2>/dev/null || true) for all /dev/dri operations
- Added adduser error handling for video/render groups
- No longer fails if no GPU is detected (graceful skip)
- Added intel-media-va-driver for newer Intel GPUs
- Improved AMD APU support with firmware packages
- Better NVIDIA handling (warning instead of failure)
This fixes installation failures in privileged containers without GPU
passthrough, where /dev/dri does not exist.
Supports: Ubuntu, Debian 12 (Bookworm), Debian 13 (Trixie)
GPU Support: Intel, AMD, NVIDIA (manual driver)
* refactor(hwaccel): complete migration for all GPU apps
Migrated remaining GPU apps to setup_hwaccel:
- fileflows-install.sh
- openwebui-install.sh (added setup_hwaccel - was missing)
- tunarr-install.sh
Also fixed tools/pve/hw-acceleration.sh:
- Added error handling for /dev/dri operations
- Added chmod 660 /dev/dri/* that was missing
- Added error suppression for adduser commands
All 13 GPU apps (var_gpu=yes) now use centralized setup_hwaccel:
jellyfin, plex, emby, ersatztv, frigate, tdarr, unmanic,
channels, ollama, immich, fileflows, openwebui, tunarr
* feat(hwaccel): complete Intel non-free driver support and GID sync
Enhanced setup_hwaccel function:
- Auto-detect Intel GPU generation (Gen 9+ for non-free drivers)
- Debian 12 (Bookworm): Add non-free repo + intel-media-va-driver-non-free
- Debian 13 (Trixie): Add non-free repo + libvpl2 + mesa-opencl-icd
- Ubuntu: Use ubuntu repos with intel-media-va-driver
- Fallback to open drivers if non-free fails
- GID sync for video/render groups (moved from install scripts)
OpenWebUI: Added Intel oneAPI support when installing Ollama
- Intel Level Zero GPU support
- Intel oneAPI Base Toolkit
- Same setup as standalone Ollama install
Cleanup:
- Removed duplicate GID sync from tdarr-install.sh
- Removed duplicate GID sync from unmanic-install.sh
* fix(ersatztv): remove duplicate HW acceleration code
Removed manual Intel HW acceleration setup that remained after
setup_hwaccel migration. The non-free driver prompt is no longer
needed as setup_hwaccel auto-detects Intel GPU generation.
2025-12-17 14:37:31 +01:00
2026-01-06 19:27:04 +01:00
# ══════════════════════════════════════════════════════════════════════════════
# Helper: Add Debian non-free-firmware repository
# ══════════════════════════════════════════════════════════════════════════════
_add_debian_nonfree_firmware( ) {
local os_codename = " $1 "
[ [ -f /etc/apt/sources.list.d/non-free-firmware.sources ] ] && return 0
case " $os_codename " in
bullseye)
# Debian 11 uses 'non-free' component (no separate non-free-firmware)
cat <<'EOF' >/etc/apt/sources.list.d/non-free-firmware.sources
Types: deb
URIs: http://deb.debian.org/debian
Suites: bullseye bullseye-updates
Components: non-free
2026-02-23 12:59:42 +01:00
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg
2025-10-22 06:25:26 -07:00
2026-01-06 19:27:04 +01:00
Types: deb
URIs: http://deb.debian.org/debian-security
Suites: bullseye-security
Components: non-free
2026-02-23 12:59:42 +01:00
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg
2026-01-06 19:27:04 +01:00
EOF
; ;
bookworm)
cat <<'EOF' >/etc/apt/sources.list.d/non-free-firmware.sources
2025-12-21 23:11:18 +01:00
Types: deb
URIs: http://deb.debian.org/debian
Suites: bookworm bookworm-updates
Components: non-free-firmware
2026-02-23 12:59:42 +01:00
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg
2025-12-21 23:11:18 +01:00
Types: deb
URIs: http://deb.debian.org/debian-security
Suites: bookworm-security
Components: non-free-firmware
2026-02-23 12:59:42 +01:00
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg
2025-12-21 23:11:18 +01:00
EOF
2026-01-06 19:27:04 +01:00
; ;
trixie | sid)
cat <<'EOF' >/etc/apt/sources.list.d/non-free-firmware.sources
2025-12-21 23:11:18 +01:00
Types: deb
URIs: http://deb.debian.org/debian
Suites: trixie trixie-updates
Components: non-free-firmware
2026-02-23 12:59:42 +01:00
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg
2025-12-21 23:11:18 +01:00
Types: deb
URIs: http://deb.debian.org/debian-security
Suites: trixie-security
Components: non-free-firmware
2026-02-23 12:59:42 +01:00
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg
2025-12-21 23:11:18 +01:00
EOF
2025-10-22 06:25:26 -07:00
; ;
esac
2026-01-06 19:27:04 +01:00
$STD apt -y update
}
# ══════════════════════════════════════════════════════════════════════════════
# Helper: Setup GPU device permissions
# ══════════════════════════════════════════════════════════════════════════════
_setup_gpu_permissions( ) {
local in_ct = " $1 "
2025-10-22 06:25:26 -07:00
2026-01-06 19:27:04 +01:00
# /dev/dri permissions (Intel/AMD)
use setup_hwaccel for robust hardware acceleration (#10054)
* fix(jellyfin): use setup_hwaccel for robust hardware acceleration
Replaces manual hardware acceleration setup with the centralized
setup_hwaccel function from tools.func.
This fixes the installation failure in privileged containers where
/dev/dri does not exist (e.g., when no GPU is passed through).
The setup_hwaccel function includes:
- Proper error handling for missing /dev/dri
- GPU vendor detection (Intel, AMD, NVIDIA)
- Graceful fallback when no GPU is available
Fixes: Installation fails with 'chgrp: cannot access /dev/dri'
when creating privileged containers without GPU passthrough.
* refactor(hwaccel): standardize hardware acceleration across all install scripts
Migrated all install scripts to use the centralized setup_hwaccel function:
- plex-install.sh
- emby-install.sh
- ersatztv-install.sh
- frigate-install.sh
- tdarr-install.sh
- unmanic-install.sh
- channels-install.sh
- ollama-install.sh
- immich-install.sh (added error handling)
Enhanced setup_hwaccel function in tools.func:
- Added -d /dev/dri check before setting permissions
- Added error handling (2>/dev/null || true) for all /dev/dri operations
- Added adduser error handling for video/render groups
- No longer fails if no GPU is detected (graceful skip)
- Added intel-media-va-driver for newer Intel GPUs
- Improved AMD APU support with firmware packages
- Better NVIDIA handling (warning instead of failure)
This fixes installation failures in privileged containers without GPU
passthrough, where /dev/dri does not exist.
Supports: Ubuntu, Debian 12 (Bookworm), Debian 13 (Trixie)
GPU Support: Intel, AMD, NVIDIA (manual driver)
* refactor(hwaccel): complete migration for all GPU apps
Migrated remaining GPU apps to setup_hwaccel:
- fileflows-install.sh
- openwebui-install.sh (added setup_hwaccel - was missing)
- tunarr-install.sh
Also fixed tools/pve/hw-acceleration.sh:
- Added error handling for /dev/dri operations
- Added chmod 660 /dev/dri/* that was missing
- Added error suppression for adduser commands
All 13 GPU apps (var_gpu=yes) now use centralized setup_hwaccel:
jellyfin, plex, emby, ersatztv, frigate, tdarr, unmanic,
channels, ollama, immich, fileflows, openwebui, tunarr
* feat(hwaccel): complete Intel non-free driver support and GID sync
Enhanced setup_hwaccel function:
- Auto-detect Intel GPU generation (Gen 9+ for non-free drivers)
- Debian 12 (Bookworm): Add non-free repo + intel-media-va-driver-non-free
- Debian 13 (Trixie): Add non-free repo + libvpl2 + mesa-opencl-icd
- Ubuntu: Use ubuntu repos with intel-media-va-driver
- Fallback to open drivers if non-free fails
- GID sync for video/render groups (moved from install scripts)
OpenWebUI: Added Intel oneAPI support when installing Ollama
- Intel Level Zero GPU support
- Intel oneAPI Base Toolkit
- Same setup as standalone Ollama install
Cleanup:
- Removed duplicate GID sync from tdarr-install.sh
- Removed duplicate GID sync from unmanic-install.sh
* fix(ersatztv): remove duplicate HW acceleration code
Removed manual Intel HW acceleration setup that remained after
setup_hwaccel migration. The non-free driver prompt is no longer
needed as setup_hwaccel auto-detects Intel GPU generation.
2025-12-17 14:37:31 +01:00
if [ [ " $in_ct " = = "0" && -d /dev/dri ] ] ; then
2026-01-05 18:03:02 +01:00
if ls /dev/dri/card* /dev/dri/renderD* & >/dev/null; then
chgrp video /dev/dri 2>/dev/null || true
chmod 755 /dev/dri 2>/dev/null || true
chmod 660 /dev/dri/* 2>/dev/null || true
$STD adduser " $( id -u -n) " video 2>/dev/null || true
$STD adduser " $( id -u -n) " render 2>/dev/null || true
2026-01-06 19:27:04 +01:00
# Sync GID with host
2026-01-05 18:03:02 +01:00
local host_video_gid host_render_gid
host_video_gid = $( getent group video | cut -d: -f3)
host_render_gid = $( getent group render | cut -d: -f3)
2026-01-06 19:27:04 +01:00
if [ [ -n " $host_video_gid " ] ] ; then
2026-01-05 18:03:02 +01:00
sed -i " s/^video:x:[0-9]*:/video:x: $host_video_gid :/ " /etc/group 2>/dev/null || true
2026-01-06 19:27:04 +01:00
fi
if [ [ -n " $host_render_gid " ] ] ; then
2026-01-05 18:03:02 +01:00
sed -i " s/^render:x:[0-9]*:/render:x: $host_render_gid :/ " /etc/group 2>/dev/null || true
fi
use setup_hwaccel for robust hardware acceleration (#10054)
* fix(jellyfin): use setup_hwaccel for robust hardware acceleration
Replaces manual hardware acceleration setup with the centralized
setup_hwaccel function from tools.func.
This fixes the installation failure in privileged containers where
/dev/dri does not exist (e.g., when no GPU is passed through).
The setup_hwaccel function includes:
- Proper error handling for missing /dev/dri
- GPU vendor detection (Intel, AMD, NVIDIA)
- Graceful fallback when no GPU is available
Fixes: Installation fails with 'chgrp: cannot access /dev/dri'
when creating privileged containers without GPU passthrough.
* refactor(hwaccel): standardize hardware acceleration across all install scripts
Migrated all install scripts to use the centralized setup_hwaccel function:
- plex-install.sh
- emby-install.sh
- ersatztv-install.sh
- frigate-install.sh
- tdarr-install.sh
- unmanic-install.sh
- channels-install.sh
- ollama-install.sh
- immich-install.sh (added error handling)
Enhanced setup_hwaccel function in tools.func:
- Added -d /dev/dri check before setting permissions
- Added error handling (2>/dev/null || true) for all /dev/dri operations
- Added adduser error handling for video/render groups
- No longer fails if no GPU is detected (graceful skip)
- Added intel-media-va-driver for newer Intel GPUs
- Improved AMD APU support with firmware packages
- Better NVIDIA handling (warning instead of failure)
This fixes installation failures in privileged containers without GPU
passthrough, where /dev/dri does not exist.
Supports: Ubuntu, Debian 12 (Bookworm), Debian 13 (Trixie)
GPU Support: Intel, AMD, NVIDIA (manual driver)
* refactor(hwaccel): complete migration for all GPU apps
Migrated remaining GPU apps to setup_hwaccel:
- fileflows-install.sh
- openwebui-install.sh (added setup_hwaccel - was missing)
- tunarr-install.sh
Also fixed tools/pve/hw-acceleration.sh:
- Added error handling for /dev/dri operations
- Added chmod 660 /dev/dri/* that was missing
- Added error suppression for adduser commands
All 13 GPU apps (var_gpu=yes) now use centralized setup_hwaccel:
jellyfin, plex, emby, ersatztv, frigate, tdarr, unmanic,
channels, ollama, immich, fileflows, openwebui, tunarr
* feat(hwaccel): complete Intel non-free driver support and GID sync
Enhanced setup_hwaccel function:
- Auto-detect Intel GPU generation (Gen 9+ for non-free drivers)
- Debian 12 (Bookworm): Add non-free repo + intel-media-va-driver-non-free
- Debian 13 (Trixie): Add non-free repo + libvpl2 + mesa-opencl-icd
- Ubuntu: Use ubuntu repos with intel-media-va-driver
- Fallback to open drivers if non-free fails
- GID sync for video/render groups (moved from install scripts)
OpenWebUI: Added Intel oneAPI support when installing Ollama
- Intel Level Zero GPU support
- Intel oneAPI Base Toolkit
- Same setup as standalone Ollama install
Cleanup:
- Removed duplicate GID sync from tdarr-install.sh
- Removed duplicate GID sync from unmanic-install.sh
* fix(ersatztv): remove duplicate HW acceleration code
Removed manual Intel HW acceleration setup that remained after
setup_hwaccel migration. The non-free driver prompt is no longer
needed as setup_hwaccel auto-detects Intel GPU generation.
2025-12-17 14:37:31 +01:00
2026-01-06 19:27:04 +01:00
# Verify VA-API
2026-01-05 18:03:02 +01:00
if command -v vainfo & >/dev/null; then
if vainfo & >/dev/null; then
2026-01-06 19:27:04 +01:00
msg_info "VA-API verified and working"
2026-01-05 18:03:02 +01:00
else
2026-01-06 19:27:04 +01:00
msg_warn "vainfo test failed - check GPU passthrough"
2026-01-05 18:03:02 +01:00
fi
fi
use setup_hwaccel for robust hardware acceleration (#10054)
* fix(jellyfin): use setup_hwaccel for robust hardware acceleration
Replaces manual hardware acceleration setup with the centralized
setup_hwaccel function from tools.func.
This fixes the installation failure in privileged containers where
/dev/dri does not exist (e.g., when no GPU is passed through).
The setup_hwaccel function includes:
- Proper error handling for missing /dev/dri
- GPU vendor detection (Intel, AMD, NVIDIA)
- Graceful fallback when no GPU is available
Fixes: Installation fails with 'chgrp: cannot access /dev/dri'
when creating privileged containers without GPU passthrough.
* refactor(hwaccel): standardize hardware acceleration across all install scripts
Migrated all install scripts to use the centralized setup_hwaccel function:
- plex-install.sh
- emby-install.sh
- ersatztv-install.sh
- frigate-install.sh
- tdarr-install.sh
- unmanic-install.sh
- channels-install.sh
- ollama-install.sh
- immich-install.sh (added error handling)
Enhanced setup_hwaccel function in tools.func:
- Added -d /dev/dri check before setting permissions
- Added error handling (2>/dev/null || true) for all /dev/dri operations
- Added adduser error handling for video/render groups
- No longer fails if no GPU is detected (graceful skip)
- Added intel-media-va-driver for newer Intel GPUs
- Improved AMD APU support with firmware packages
- Better NVIDIA handling (warning instead of failure)
This fixes installation failures in privileged containers without GPU
passthrough, where /dev/dri does not exist.
Supports: Ubuntu, Debian 12 (Bookworm), Debian 13 (Trixie)
GPU Support: Intel, AMD, NVIDIA (manual driver)
* refactor(hwaccel): complete migration for all GPU apps
Migrated remaining GPU apps to setup_hwaccel:
- fileflows-install.sh
- openwebui-install.sh (added setup_hwaccel - was missing)
- tunarr-install.sh
Also fixed tools/pve/hw-acceleration.sh:
- Added error handling for /dev/dri operations
- Added chmod 660 /dev/dri/* that was missing
- Added error suppression for adduser commands
All 13 GPU apps (var_gpu=yes) now use centralized setup_hwaccel:
jellyfin, plex, emby, ersatztv, frigate, tdarr, unmanic,
channels, ollama, immich, fileflows, openwebui, tunarr
* feat(hwaccel): complete Intel non-free driver support and GID sync
Enhanced setup_hwaccel function:
- Auto-detect Intel GPU generation (Gen 9+ for non-free drivers)
- Debian 12 (Bookworm): Add non-free repo + intel-media-va-driver-non-free
- Debian 13 (Trixie): Add non-free repo + libvpl2 + mesa-opencl-icd
- Ubuntu: Use ubuntu repos with intel-media-va-driver
- Fallback to open drivers if non-free fails
- GID sync for video/render groups (moved from install scripts)
OpenWebUI: Added Intel oneAPI support when installing Ollama
- Intel Level Zero GPU support
- Intel oneAPI Base Toolkit
- Same setup as standalone Ollama install
Cleanup:
- Removed duplicate GID sync from tdarr-install.sh
- Removed duplicate GID sync from unmanic-install.sh
* fix(ersatztv): remove duplicate HW acceleration code
Removed manual Intel HW acceleration setup that remained after
setup_hwaccel migration. The non-free driver prompt is no longer
needed as setup_hwaccel auto-detects Intel GPU generation.
2025-12-17 14:37:31 +01:00
fi
2025-09-11 12:44:13 +02:00
fi
2025-10-22 06:25:26 -07:00
2026-01-06 19:27:04 +01:00
# /dev/nvidia* permissions (NVIDIA)
if ls /dev/nvidia* & >/dev/null 2>& 1; then
msg_info "Configuring NVIDIA device permissions"
for nvidia_dev in /dev/nvidia*; do
[ [ -e " $nvidia_dev " ] ] && {
chgrp video " $nvidia_dev " 2>/dev/null || true
chmod 666 " $nvidia_dev " 2>/dev/null || true
}
done
if [ [ -d /dev/nvidia-caps ] ] ; then
chmod 755 /dev/nvidia-caps 2>/dev/null || true
for caps_dev in /dev/nvidia-caps/*; do
[ [ -e " $caps_dev " ] ] && {
chgrp video " $caps_dev " 2>/dev/null || true
chmod 666 " $caps_dev " 2>/dev/null || true
}
done
fi
# Verify nvidia-smi
if command -v nvidia-smi & >/dev/null; then
if nvidia-smi & >/dev/null; then
msg_info "nvidia-smi verified and working"
else
msg_warn "nvidia-smi test failed - check driver version match"
fi
fi
fi
# /dev/kfd permissions (AMD ROCm)
if [ [ -e /dev/kfd ] ] ; then
chmod 666 /dev/kfd 2>/dev/null || true
msg_info "AMD ROCm compute device configured"
fi
2025-09-11 12:44:13 +02:00
}
# ------------------------------------------------------------------------------
# Installs ImageMagick 7 from source (Debian/Ubuntu only).
#
# Description:
# - Downloads the latest ImageMagick source tarball
# - Builds and installs ImageMagick to /usr/local
# - Configures dynamic linker (ldconfig)
#
# Notes:
# - Requires: build-essential, libtool, libjpeg-dev, libpng-dev, etc.
# ------------------------------------------------------------------------------
function setup_imagemagick( ) {
2025-10-22 06:25:26 -07:00
local TMP_DIR = $( mktemp -d)
2025-09-11 12:44:13 +02:00
local BINARY_PATH = "/usr/local/bin/magick"
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Get currently installed version
local INSTALLED_VERSION = ""
2025-09-11 12:44:13 +02:00
if command -v magick & >/dev/null; then
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
INSTALLED_VERSION = $( magick -version | awk '/^Version/ {print $3}' )
2025-09-11 12:44:13 +02:00
fi
2025-10-22 06:25:26 -07:00
msg_info "Setup ImageMagick"
ensure_dependencies \
2025-09-11 12:44:13 +02:00
build-essential \
libtool \
libjpeg-dev \
libpng-dev \
libtiff-dev \
libwebp-dev \
libheif-dev \
libde265-dev \
libopenjp2-7-dev \
libxml2-dev \
liblcms2-dev \
libfreetype6-dev \
libraw-dev \
libfftw3-dev \
liblqr-1-0-dev \
libgsl-dev \
pkg-config \
ghostscript
2025-04-28 15:25:10 +02:00
2025-10-22 06:25:26 -07:00
curl -fsSL https://imagemagick.org/archive/ImageMagick.tar.gz -o " $TMP_DIR /ImageMagick.tar.gz " || {
msg_error "Failed to download ImageMagick"
rm -rf " $TMP_DIR "
return 1
}
tar -xzf " $TMP_DIR /ImageMagick.tar.gz " -C " $TMP_DIR " || {
msg_error "Failed to extract ImageMagick"
rm -rf " $TMP_DIR "
return 1
}
2025-09-11 12:44:13 +02:00
cd " $TMP_DIR " /ImageMagick-* || {
msg_error "Source extraction failed"
rm -rf " $TMP_DIR "
2025-05-05 15:47:43 +02:00
return 1
}
2025-04-28 15:25:10 +02:00
2025-10-22 06:25:26 -07:00
$STD ./configure --disable-static || {
msg_error "ImageMagick configure failed"
rm -rf " $TMP_DIR "
return 1
}
$STD make -j" $( nproc) " || {
msg_error "ImageMagick compilation failed"
rm -rf " $TMP_DIR "
return 1
}
$STD make install || {
msg_error "ImageMagick installation failed"
rm -rf " $TMP_DIR "
return 1
}
2025-09-11 12:44:13 +02:00
$STD ldconfig /usr/local/lib
2025-04-28 15:25:10 +02:00
2025-09-11 12:44:13 +02:00
if [ [ ! -x " $BINARY_PATH " ] ] ; then
msg_error "ImageMagick installation failed"
rm -rf " $TMP_DIR "
return 1
fi
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
local FINAL_VERSION
FINAL_VERSION = $( " $BINARY_PATH " -version | awk '/^Version/ {print $3}' )
2025-09-11 12:44:13 +02:00
rm -rf " $TMP_DIR "
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
cache_installed_version "imagemagick" " $FINAL_VERSION "
2025-09-11 12:44:13 +02:00
ensure_usr_local_bin_persist
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
if [ [ -n " $INSTALLED_VERSION " ] ] ; then
msg_ok " Upgrade ImageMagick $INSTALLED_VERSION → $FINAL_VERSION "
else
msg_ok " Setup ImageMagick $FINAL_VERSION "
fi
2025-04-28 15:25:10 +02:00
}
2025-05-15 15:18:41 +02:00
# ------------------------------------------------------------------------------
# Installs Temurin JDK via Adoptium APT repository.
#
# Description:
# - Removes previous JDK if version mismatch
# - Installs or upgrades to specified JAVA_VERSION
#
# Variables:
# JAVA_VERSION - Temurin JDK version to install (e.g. 17, 21)
# ------------------------------------------------------------------------------
2025-06-18 12:07:08 +02:00
function setup_java( ) {
2025-05-05 15:47:43 +02:00
local JAVA_VERSION = " ${ JAVA_VERSION :- 21 } "
2025-10-22 06:25:26 -07:00
local DISTRO_ID DISTRO_CODENAME
DISTRO_ID = $( awk -F= '/^ID=/{print $2}' /etc/os-release | tr -d '"' )
2025-05-05 15:47:43 +02:00
DISTRO_CODENAME = $( awk -F= '/VERSION_CODENAME/ { print $2 }' /etc/os-release)
local DESIRED_PACKAGE = " temurin- ${ JAVA_VERSION } -jdk "
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Prepare repository (cleanup + validation)
prepare_repository_setup "adoptium" || {
msg_error "Failed to prepare Adoptium repository"
return 1
}
2025-10-22 06:25:26 -07:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Add repo if needed
2025-10-22 06:25:26 -07:00
if [ [ ! -f /etc/apt/sources.list.d/adoptium.sources ] ] ; then
local SUITE
SUITE = $( get_fallback_suite " $DISTRO_ID " " $DISTRO_CODENAME " "https://packages.adoptium.net/artifactory/deb" )
setup_deb822_repo \
"adoptium" \
"https://packages.adoptium.net/artifactory/api/gpg/key/public" \
"https://packages.adoptium.net/artifactory/deb" \
" $SUITE " \
2025-11-07 02:49:16 -08:00
"main"
2025-05-05 15:47:43 +02:00
fi
2025-04-28 15:25:10 +02:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Get currently installed version
2025-05-05 15:47:43 +02:00
local INSTALLED_VERSION = ""
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
if dpkg -l | grep -q "temurin-.*-jdk" 2>/dev/null; then
INSTALLED_VERSION = $( dpkg -l 2>/dev/null | awk '/temurin-.*-jdk/{print $2}' | grep -oP 'temurin-\K[0-9]+' | head -n1 || echo "" )
2025-05-05 15:47:43 +02:00
fi
2025-04-28 15:25:10 +02:00
2025-12-04 09:20:32 +01:00
# Validate INSTALLED_VERSION is not empty if JDK package found
2025-11-11 16:19:35 +01:00
local JDK_COUNT = 0
2025-11-13 10:17:51 +01:00
JDK_COUNT = $( dpkg -l 2>/dev/null | grep -c "temurin-.*-jdk" || true )
2025-11-11 16:19:35 +01:00
if [ [ -z " $INSTALLED_VERSION " && " ${ JDK_COUNT :- 0 } " -gt 0 ] ] ; then
2025-12-04 09:20:32 +01:00
msg_warn "Found Temurin JDK but cannot determine version - attempting reinstall"
# Try to get actual package name for purge
local OLD_PACKAGE
OLD_PACKAGE = $( dpkg -l 2>/dev/null | awk '/temurin-.*-jdk/{print $2}' | head -n1 || echo "" )
if [ [ -n " $OLD_PACKAGE " ] ] ; then
msg_info " Removing existing package: $OLD_PACKAGE "
$STD apt purge -y " $OLD_PACKAGE " || true
fi
INSTALLED_VERSION = "" # Reset to trigger fresh install
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
fi
2025-04-28 15:25:10 +02:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Scenario 1: Already at correct version
if [ [ " $INSTALLED_VERSION " = = " $JAVA_VERSION " ] ] ; then
msg_info " Update Temurin JDK $JAVA_VERSION "
ensure_apt_working || return 1
upgrade_packages_with_retry " $DESIRED_PACKAGE " || {
msg_error "Failed to update Temurin JDK"
2025-10-22 06:25:26 -07:00
return 1
}
cache_installed_version "temurin-jdk" " $JAVA_VERSION "
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
msg_ok " Update Temurin JDK $JAVA_VERSION "
return 0
fi
# Scenario 2: Different version - remove old and install new
if [ [ -n " $INSTALLED_VERSION " ] ] ; then
msg_info " Upgrade Temurin JDK from $INSTALLED_VERSION to $JAVA_VERSION "
$STD apt purge -y " temurin- ${ INSTALLED_VERSION } -jdk " || true
else
msg_info " Setup Temurin JDK $JAVA_VERSION "
2025-09-11 12:44:13 +02:00
fi
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
ensure_apt_working || return 1
# Install with retry logic
install_packages_with_retry " $DESIRED_PACKAGE " || {
msg_error " Failed to install Temurin JDK $JAVA_VERSION "
return 1
}
cache_installed_version "temurin-jdk" " $JAVA_VERSION "
msg_ok " Setup Temurin JDK $JAVA_VERSION "
2025-09-11 12:44:13 +02:00
}
2025-06-18 12:07:08 +02:00
2025-09-11 12:44:13 +02:00
# ------------------------------------------------------------------------------
# Installs a local IP updater script using networkd-dispatcher.
#
# Description:
# - Stores current IP in /run/local-ip.env
# - Automatically runs on network changes
# ------------------------------------------------------------------------------
2025-06-18 12:07:08 +02:00
2025-09-11 12:44:13 +02:00
function setup_local_ip_helper( ) {
local BASE_DIR = "/usr/local/community-scripts/ip-management"
local SCRIPT_PATH = " $BASE_DIR /update_local_ip.sh "
local IP_FILE = "/run/local-ip.env"
local DISPATCHER_SCRIPT = "/etc/networkd-dispatcher/routable.d/10-update-local-ip.sh"
2025-06-18 12:07:08 +02:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Check if already set up
if [ [ -f " $SCRIPT_PATH " && -f " $DISPATCHER_SCRIPT " ] ] ; then
msg_info "Update Local IP Helper"
cache_installed_version "local-ip-helper" "1.0"
msg_ok "Update Local IP Helper"
else
msg_info "Setup Local IP Helper"
fi
2025-09-11 12:44:13 +02:00
mkdir -p " $BASE_DIR "
2025-06-18 12:07:08 +02:00
2025-09-11 12:44:13 +02:00
# Install networkd-dispatcher if not present
if ! dpkg -s networkd-dispatcher >/dev/null 2>& 1; then
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
ensure_dependencies networkd-dispatcher || {
2025-10-22 06:25:26 -07:00
msg_error "Failed to install networkd-dispatcher"
return 1
}
2025-09-11 12:44:13 +02:00
fi
2025-06-18 12:07:08 +02:00
2025-09-11 12:44:13 +02:00
# Write update_local_ip.sh
cat <<'EOF' >" $SCRIPT_PATH "
#!/bin/bash
set -euo pipefail
2025-06-18 12:07:08 +02:00
2025-09-11 12:44:13 +02:00
IP_FILE = "/run/local-ip.env"
mkdir -p " $( dirname " $IP_FILE " ) "
2025-06-18 12:07:08 +02:00
2025-09-11 12:44:13 +02:00
get_current_ip( ) {
local ip
2025-06-30 20:23:25 +02:00
2026-01-23 09:05:17 +01:00
# Try IPv4 targets first
local ipv4_targets = ( "8.8.8.8" "1.1.1.1" "192.168.1.1" "10.0.0.1" "172.16.0.1" "default" )
for target in " ${ ipv4_targets [@] } " ; do
2025-09-11 12:44:13 +02:00
if [ [ " $target " = = "default" ] ] ; then
ip = $( ip route get 1 2>/dev/null | awk '{for(i=1;i<=NF;i++) if ($i=="src") print $(i+1)}' )
else
ip = $( ip route get " $target " 2>/dev/null | awk '{for(i=1;i<=NF;i++) if ($i=="src") print $(i+1)}' )
2025-06-30 20:23:25 +02:00
fi
2025-09-11 12:44:13 +02:00
if [ [ -n " $ip " ] ] ; then
echo " $ip "
return 0
fi
done
2025-06-18 12:07:08 +02:00
2026-01-23 09:05:17 +01:00
# IPv6 fallback: Try direct interface lookup for eth0
ip = $( ip -6 addr show eth0 scope global 2>/dev/null | awk '/inet6 / {print $2}' | cut -d/ -f1 | head -n1)
if [ [ -n " $ip " && " $ip " = ~ : ] ] ; then
echo " $ip "
return 0
fi
# IPv6 fallback: Use routing table with IPv6 targets (Google DNS, Cloudflare DNS)
local ipv6_targets = ( "2001:4860:4860::8888" "2606:4700:4700::1111" )
for target in " ${ ipv6_targets [@] } " ; do
ip = $( ip -6 route get " $target " 2>/dev/null | awk '{for(i=1;i<=NF;i++) if ($i=="src") print $(i+1)}' )
if [ [ -n " $ip " && " $ip " = ~ : ] ] ; then
echo " $ip "
return 0
fi
done
2025-09-11 12:44:13 +02:00
return 1
}
2025-06-18 12:07:08 +02:00
2025-09-11 12:44:13 +02:00
current_ip = " $( get_current_ip) "
2025-06-18 12:07:08 +02:00
2025-09-11 12:44:13 +02:00
if [ [ -z " $current_ip " ] ] ; then
echo "[ERROR] Could not detect local IP" >& 2
exit 1
fi
2025-06-18 12:07:08 +02:00
2025-09-11 12:44:13 +02:00
if [ [ -f " $IP_FILE " ] ] ; then
source " $IP_FILE "
[ [ " $LOCAL_IP " = = " $current_ip " ] ] && exit 0
fi
2025-06-18 12:07:08 +02:00
2025-09-11 12:44:13 +02:00
echo " LOCAL_IP= $current_ip " > " $IP_FILE "
echo " [INFO] LOCAL_IP updated to $current_ip "
EOF
2025-06-18 12:07:08 +02:00
2025-09-11 12:44:13 +02:00
chmod +x " $SCRIPT_PATH "
2025-05-14 16:08:21 +02:00
2025-09-11 12:44:13 +02:00
# Install dispatcher hook
mkdir -p " $( dirname " $DISPATCHER_SCRIPT " ) "
cat <<EOF >"$DISPATCHE R_SCRIPT"
#!/bin/bash
$SCRIPT_PATH
EOF
2025-06-18 12:07:08 +02:00
2025-09-11 12:44:13 +02:00
chmod +x " $DISPATCHER_SCRIPT "
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
systemctl enable -q --now networkd-dispatcher.service || {
msg_warn "Failed to enable networkd-dispatcher service"
}
cache_installed_version "local-ip-helper" "1.0"
msg_ok "Setup Local IP Helper"
2025-09-11 12:44:13 +02:00
}
2025-06-18 12:07:08 +02:00
2025-09-11 12:44:13 +02:00
# ------------------------------------------------------------------------------
2026-01-22 11:33:13 +01:00
# Installs or updates MariaDB.
2025-09-11 12:44:13 +02:00
#
# Description:
2026-01-22 11:33:13 +01:00
# - Uses Debian/Ubuntu distribution packages by default (most reliable)
# - Only uses official MariaDB repository when a specific version is requested
2025-09-11 12:44:13 +02:00
# - Detects current MariaDB version and replaces it if necessary
# - Preserves existing database data
#
# Variables:
2026-01-22 11:33:13 +01:00
# MARIADB_VERSION - MariaDB version to install (optional)
# - Not set or "latest": Uses distribution packages (recommended)
# - Specific version (e.g. "11.4", "12.2"): Uses MariaDB official repo
2025-09-11 12:44:13 +02:00
# ------------------------------------------------------------------------------
2025-07-09 14:06:33 +02:00
2025-09-11 12:44:13 +02:00
setup_mariadb( ) {
local MARIADB_VERSION = " ${ MARIADB_VERSION :- latest } "
2026-01-22 11:33:13 +01:00
local USE_DISTRO_PACKAGES = false
2025-09-11 12:44:13 +02:00
2026-01-12 08:48:36 +01:00
# Ensure non-interactive mode for all apt operations
export DEBIAN_FRONTEND = noninteractive
export NEEDRESTART_MODE = a
export NEEDRESTART_SUSPEND = 1
2026-01-22 11:33:13 +01:00
# Determine installation method:
# - "latest" or empty: Use distribution packages (avoids mirror issues)
# - Specific version: Use MariaDB official repository
if [ [ " $MARIADB_VERSION " = = "latest" || -z " $MARIADB_VERSION " ] ] ; then
USE_DISTRO_PACKAGES = true
msg_info "Setup MariaDB (distribution packages)"
else
msg_info " Setup MariaDB $MARIADB_VERSION (official repository) "
2025-09-11 12:44:13 +02:00
fi
2025-05-14 16:08:21 +02:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Get currently installed version
2025-09-11 12:44:13 +02:00
local CURRENT_VERSION = ""
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
CURRENT_VERSION = $( is_tool_installed "mariadb" 2>/dev/null) || true
2026-01-12 08:48:36 +01:00
# Pre-configure debconf to prevent any interactive prompts during install/upgrade
2026-01-22 11:33:13 +01:00
debconf-set-selections <<EOF
2026-01-12 08:48:36 +01:00
mariadb-server mariadb-server/feedback boolean false
mariadb-server mariadb-server/root_password password
mariadb-server mariadb-server/root_password_again password
EOF
2026-01-22 11:33:13 +01:00
# If specific version requested, also configure version-specific debconf
if [ [ " $USE_DISTRO_PACKAGES " = = "false" ] ] ; then
local MARIADB_MAJOR_MINOR
MARIADB_MAJOR_MINOR = $( echo " $MARIADB_VERSION " | awk -F. '{print $1"."$2}' )
if [ [ -n " $MARIADB_MAJOR_MINOR " ] ] ; then
debconf-set-selections <<EOF
mariadb-server-$MARIADB_MAJOR_MINOR mariadb-server/feedback boolean false
mariadb-server-$MARIADB_MAJOR_MINOR mariadb-server/root_password password
mariadb-server-$MARIADB_MAJOR_MINOR mariadb-server/root_password_again password
EOF
fi
fi
# ============================================================================
# DISTRIBUTION PACKAGES PATH (default, most reliable)
# ============================================================================
if [ [ " $USE_DISTRO_PACKAGES " = = "true" ] ] ; then
# Check if MariaDB was previously installed from official repo
local HAD_MARIADB_REPO = false
if [ [ -f /etc/apt/sources.list.d/mariadb.sources ] ] || [ [ -f /etc/apt/sources.list.d/mariadb.list ] ] ; then
HAD_MARIADB_REPO = true
msg_info "Removing MariaDB official repository (switching to distribution packages)"
fi
# Clean up any existing MariaDB repository files to avoid conflicts
cleanup_old_repo_files "mariadb"
# If we had a repo, we need to refresh APT cache
if [ [ " $HAD_MARIADB_REPO " = = "true" ] ] ; then
$STD apt update || msg_warn "APT update had issues, continuing..."
fi
# Ensure APT is working
ensure_apt_working || return 1
# Check if installed version is from official repo and higher than distro version
# In this case, we keep the existing installation to avoid data issues
if [ [ -n " $CURRENT_VERSION " ] ] ; then
# Get available distro version
local DISTRO_VERSION = ""
DISTRO_VERSION = $( apt-cache policy mariadb-server 2>/dev/null | grep -E "Candidate:" | awk '{print $2}' | grep -oP '^\d+:\K\d+\.\d+\.\d+' || echo "" )
if [ [ -n " $DISTRO_VERSION " ] ] ; then
# Compare versions - if current is higher, keep it
local CURRENT_MAJOR DISTRO_MAJOR
CURRENT_MAJOR = $( echo " $CURRENT_VERSION " | awk -F. '{print $1}' )
DISTRO_MAJOR = $( echo " $DISTRO_VERSION " | awk -F. '{print $1}' )
if [ [ " $CURRENT_MAJOR " -gt " $DISTRO_MAJOR " ] ] ; then
msg_warn " MariaDB $CURRENT_VERSION is already installed (higher than distro $DISTRO_VERSION ) "
msg_warn "Keeping existing installation to preserve data integrity"
msg_warn "To use distribution packages, manually remove MariaDB first"
_setup_mariadb_runtime_dir
cache_installed_version "mariadb" " $CURRENT_VERSION "
msg_ok " Setup MariaDB $CURRENT_VERSION (existing installation kept) "
return 0
fi
fi
fi
# Install or upgrade MariaDB from distribution packages
if ! install_packages_with_retry "mariadb-server" "mariadb-client" ; then
msg_error "Failed to install MariaDB packages from distribution"
return 1
fi
# Get installed version for caching
local INSTALLED_VERSION = ""
INSTALLED_VERSION = $( mariadb --version 2>/dev/null | grep -oP '\d+\.\d+\.\d+' | head -n1 || echo "distro" )
# Configure runtime directory and finish
_setup_mariadb_runtime_dir
cache_installed_version "mariadb" " $INSTALLED_VERSION "
msg_ok " Setup MariaDB $INSTALLED_VERSION (distribution packages) "
return 0
fi
# ============================================================================
# OFFICIAL REPOSITORY PATH (only when specific version requested)
# ============================================================================
# First, check if there's an old/broken repository that needs cleanup
if [ [ -f /etc/apt/sources.list.d/mariadb.sources ] ] || [ [ -f /etc/apt/sources.list.d/mariadb.list ] ] ; then
local OLD_REPO_VERSION = ""
2026-02-22 11:54:21 +01:00
OLD_REPO_VERSION = $( grep -oP 'repo/\K[0-9]+\.[0-9]+(\.[0-9]+)?' /etc/apt/sources.list.d/mariadb.sources 2>/dev/null ||
grep -oP 'repo/\K[0-9]+\.[0-9]+(\.[0-9]+)?' /etc/apt/sources.list.d/mariadb.list 2>/dev/null || echo "" )
2026-01-22 11:33:13 +01:00
# Check if old repo points to a different version
if [ [ -n " $OLD_REPO_VERSION " ] ] && [ [ " ${ OLD_REPO_VERSION %.* } " != " ${ MARIADB_VERSION %.* } " ] ] ; then
msg_info " Cleaning up old MariaDB repository (was: $OLD_REPO_VERSION , requested: $MARIADB_VERSION ) "
cleanup_old_repo_files "mariadb"
$STD apt update || msg_warn "APT update had issues, continuing..."
fi
2026-01-12 08:48:36 +01:00
fi
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Scenario 1: Already installed at target version - just update packages
if [ [ -n " $CURRENT_VERSION " && " $CURRENT_VERSION " = = " $MARIADB_VERSION " ] ] ; then
msg_info " Update MariaDB $MARIADB_VERSION "
# Ensure APT is working
ensure_apt_working || return 1
# Check if repository needs to be refreshed
if [ [ -f /etc/apt/sources.list.d/mariadb.sources ] ] ; then
local REPO_VERSION = ""
REPO_VERSION = $( grep -oP 'repo/\K[0-9]+\.[0-9]+' /etc/apt/sources.list.d/mariadb.sources 2>/dev/null || echo "" )
if [ [ -n " $REPO_VERSION " && " $REPO_VERSION " != " ${ MARIADB_VERSION %.* } " ] ] ; then
msg_warn "Repository version mismatch, updating..."
manage_tool_repository "mariadb" " $MARIADB_VERSION " " http://mirror.mariadb.org/repo/ $MARIADB_VERSION " \
"https://mariadb.org/mariadb_release_signing_key.asc" || {
msg_error "Failed to update MariaDB repository"
return 1
}
fi
2025-10-22 06:25:26 -07:00
fi
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Perform upgrade with retry logic
ensure_apt_working || return 1
upgrade_packages_with_retry "mariadb-server" "mariadb-client" || {
msg_error "Failed to upgrade MariaDB packages"
return 1
}
cache_installed_version "mariadb" " $MARIADB_VERSION "
msg_ok " Update MariaDB $MARIADB_VERSION "
2025-09-11 12:44:13 +02:00
return 0
fi
2025-07-09 14:06:33 +02:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Scenario 2: Different version installed - clean upgrade
if [ [ -n " $CURRENT_VERSION " && " $CURRENT_VERSION " != " $MARIADB_VERSION " ] ] ; then
msg_info " Upgrade MariaDB from $CURRENT_VERSION to $MARIADB_VERSION "
remove_old_tool_version "mariadb"
2025-09-11 12:44:13 +02:00
fi
2025-06-18 12:07:08 +02:00
2026-01-22 11:33:13 +01:00
# Scenario 3: Fresh install or version change with specific version
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Prepare repository (cleanup + validation)
prepare_repository_setup "mariadb" || {
msg_error "Failed to prepare MariaDB repository"
return 1
}
2025-10-22 06:25:26 -07:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Install required dependencies first
2025-10-22 06:25:26 -07:00
local mariadb_deps = ( )
for dep in gawk rsync socat libdbi-perl pv; do
if apt-cache search " ^ ${ dep } $" 2>/dev/null | grep -q .; then
mariadb_deps += ( " $dep " )
fi
done
if [ [ ${# mariadb_deps [@] } -gt 0 ] ] ; then
$STD apt install -y " ${ mariadb_deps [@] } " 2>/dev/null || true
fi
2025-09-11 12:44:13 +02:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Setup repository
manage_tool_repository "mariadb" " $MARIADB_VERSION " " http://mirror.mariadb.org/repo/ $MARIADB_VERSION " \
"https://mariadb.org/mariadb_release_signing_key.asc" || {
msg_error "Failed to setup MariaDB repository"
return 1
}
2025-09-11 12:44:13 +02:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Install packages with retry logic
if ! install_packages_with_retry "mariadb-server" "mariadb-client" ; then
2026-01-22 11:33:13 +01:00
# Fallback: try distribution packages
msg_warn " Failed to install MariaDB $MARIADB_VERSION from official repo, falling back to distribution packages... "
2025-10-22 06:25:26 -07:00
cleanup_old_repo_files "mariadb"
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
$STD apt update || {
msg_warn "APT update also failed, continuing with cache"
}
2026-01-22 11:33:13 +01:00
if install_packages_with_retry "mariadb-server" "mariadb-client" ; then
local FALLBACK_VERSION = ""
FALLBACK_VERSION = $( mariadb --version 2>/dev/null | grep -oP '\d+\.\d+\.\d+' | head -n1 || echo "distro" )
msg_warn " Installed MariaDB $FALLBACK_VERSION from distribution instead of requested $MARIADB_VERSION "
_setup_mariadb_runtime_dir
cache_installed_version "mariadb" " $FALLBACK_VERSION "
msg_ok " Setup MariaDB $FALLBACK_VERSION (fallback to distribution packages) "
return 0
else
msg_error "Failed to install MariaDB packages (both official repo and distribution)"
2025-09-12 21:28:28 +02:00
return 1
2026-01-22 11:33:13 +01:00
fi
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
fi
2025-06-18 12:07:08 +02:00
2026-01-22 11:33:13 +01:00
_setup_mariadb_runtime_dir
cache_installed_version "mariadb" " $MARIADB_VERSION "
msg_ok " Setup MariaDB $MARIADB_VERSION "
}
# ------------------------------------------------------------------------------
# Helper function: Configure MariaDB runtime directory persistence
# ------------------------------------------------------------------------------
_setup_mariadb_runtime_dir( ) {
2026-01-01 23:53:53 +01:00
# Configure tmpfiles.d to ensure /run/mysqld directory is created on boot
# This fixes the issue where MariaDB fails to start after container reboot
2026-01-05 18:03:02 +01:00
2026-01-01 23:53:53 +01:00
# Create tmpfiles.d configuration with error handling
2026-01-05 18:03:02 +01:00
if ! printf '# Ensure /run/mysqld directory exists with correct permissions for MariaDB\nd /run/mysqld 0755 mysql mysql -\n' >/etc/tmpfiles.d/mariadb.conf; then
2026-01-01 23:53:53 +01:00
msg_warn "Failed to create /etc/tmpfiles.d/mariadb.conf - runtime directory may not persist on reboot"
fi
2026-01-05 18:03:02 +01:00
2026-01-01 23:53:53 +01:00
# Create the directory now if it doesn't exist
# Verify mysql user exists before attempting ownership change
if [ [ ! -d /run/mysqld ] ] ; then
mkdir -p /run/mysqld
# Set permissions first (works regardless of user existence)
chmod 755 /run/mysqld
# Set ownership only if mysql user exists
if getent passwd mysql >/dev/null 2>& 1; then
chown mysql:mysql /run/mysqld
else
msg_warn "mysql user not found - directory created with correct permissions but ownership not set"
fi
fi
2025-09-11 12:44:13 +02:00
}
2025-06-18 12:07:08 +02:00
2025-11-10 18:51:02 +01:00
# ------------------------------------------------------------------------------
# Creates MariaDB database with user, charset and optional extra grants/modes
#
# Description:
# - Generates password if empty
# - Creates database with utf8mb4_unicode_ci
# - Creates local user with password
# - Grants full access to this DB
# - Optional: apply extra GRANT statements (comma-separated)
# - Optional: apply custom GLOBAL sql_mode
# - Saves credentials to file
# - Exports variables for use in calling script
#
# Usage:
# MARIADB_DB_NAME="myapp_db" MARIADB_DB_USER="myapp_user" setup_mariadb_db
# MARIADB_DB_NAME="domain_monitor" MARIADB_DB_USER="domainmonitor" setup_mariadb_db
# MARIADB_DB_NAME="myapp" MARIADB_DB_USER="myapp" MARIADB_DB_EXTRA_GRANTS="GRANT SELECT ON \`mysql\`.\`time_zone_name\`" setup_mariadb_db
# MARIADB_DB_NAME="ghostfolio" MARIADB_DB_USER="ghostfolio" MARIADB_DB_SQL_MODE="" setup_mariadb_db
#
# Variables:
# MARIADB_DB_NAME - Database name (required)
# MARIADB_DB_USER - Database user (required)
# MARIADB_DB_PASS - User password (optional, auto-generated if empty)
# MARIADB_DB_EXTRA_GRANTS - Comma-separated GRANT statements (optional)
# Example: "GRANT SELECT ON \`mysql\`.\`time_zone_name\`"
# MARIADB_DB_SQL_MODE - Optional global sql_mode override (e.g. "", "STRICT_TRANS_TABLES")
# MARIADB_DB_CREDS_FILE - Credentials file path (optional, default: ~/${APPLICATION}.creds)
#
# Exports:
# MARIADB_DB_NAME, MARIADB_DB_USER, MARIADB_DB_PASS
# ------------------------------------------------------------------------------
function setup_mariadb_db( ) {
if [ [ -z " ${ MARIADB_DB_NAME :- } " || -z " ${ MARIADB_DB_USER :- } " ] ] ; then
msg_error "MARIADB_DB_NAME and MARIADB_DB_USER must be set before calling setup_mariadb_db"
return 1
fi
if [ [ -z " ${ MARIADB_DB_PASS :- } " ] ] ; then
MARIADB_DB_PASS = $( openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13)
fi
msg_info "Setting up MariaDB Database"
$STD mariadb -u root -e " CREATE DATABASE \` $MARIADB_DB_NAME \` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; "
$STD mariadb -u root -e " CREATE USER ' $MARIADB_DB_USER '@'localhost' IDENTIFIED BY ' $MARIADB_DB_PASS '; "
$STD mariadb -u root -e " GRANT ALL ON \` $MARIADB_DB_NAME \`.* TO ' $MARIADB_DB_USER '@'localhost'; "
# Optional extra grants
if [ [ -n " ${ MARIADB_DB_EXTRA_GRANTS :- } " ] ] ; then
IFS = ',' read -ra G_LIST <<< " ${ MARIADB_DB_EXTRA_GRANTS :- } "
for g in " ${ G_LIST [@] } " ; do
g = $( echo " $g " | xargs)
$STD mariadb -u root -e " $g TO ' $MARIADB_DB_USER '@'localhost'; "
done
fi
# Optional sql_mode override
if [ [ -n " ${ MARIADB_DB_SQL_MODE :- } " ] ] ; then
$STD mariadb -u root -e " SET GLOBAL sql_mode=' ${ MARIADB_DB_SQL_MODE :- } '; "
fi
$STD mariadb -u root -e "FLUSH PRIVILEGES;"
2025-11-17 16:52:11 +01:00
local app_name = " ${ APPLICATION ,, } "
local CREDS_FILE = " ${ MARIADB_DB_CREDS_FILE :- ${ HOME } / ${ app_name } .creds } "
2025-11-10 18:51:02 +01:00
{
echo "MariaDB Credentials"
echo " Database: $MARIADB_DB_NAME "
echo " User: $MARIADB_DB_USER "
echo " Password: $MARIADB_DB_PASS "
} >>" $CREDS_FILE "
msg_ok "Set up MariaDB Database"
export MARIADB_DB_NAME
export MARIADB_DB_USER
export MARIADB_DB_PASS
}
2025-09-11 12:44:13 +02:00
# ------------------------------------------------------------------------------
# Installs or updates MongoDB to specified major version.
#
# Description:
# - Preserves data across installations
# - Adds official MongoDB repo
#
# Variables:
# MONGO_VERSION - MongoDB major version to install (e.g. 7.0, 8.0)
# ------------------------------------------------------------------------------
2025-07-08 17:19:51 +02:00
2025-09-11 12:44:13 +02:00
function setup_mongodb( ) {
local MONGO_VERSION = " ${ MONGO_VERSION :- 8 .0 } "
2025-10-22 06:25:26 -07:00
local DISTRO_ID DISTRO_CODENAME
2025-10-22 16:17:20 +02:00
DISTRO_ID = $( get_os_info id)
DISTRO_CODENAME = $( get_os_info codename)
2025-07-08 17:19:51 +02:00
2026-01-12 08:48:36 +01:00
# Ensure non-interactive mode for all apt operations
export DEBIAN_FRONTEND = noninteractive
export NEEDRESTART_MODE = a
export NEEDRESTART_SUSPEND = 1
2025-09-11 12:44:13 +02:00
# Check AVX support
if ! grep -qm1 'avx[^ ]*' /proc/cpuinfo; then
local major = " ${ MONGO_VERSION %%.* } "
if ( ( major > 5) ) ; then
msg_error " MongoDB ${ MONGO_VERSION } requires AVX support, which is not available on this system. "
2025-06-18 12:07:08 +02:00
return 1
2025-07-08 17:19:51 +02:00
fi
2025-09-11 12:44:13 +02:00
fi
2025-06-18 12:07:08 +02:00
2025-09-11 12:44:13 +02:00
case " $DISTRO_ID " in
ubuntu)
MONGO_BASE_URL = "https://repo.mongodb.org/apt/ubuntu"
; ;
debian)
MONGO_BASE_URL = "https://repo.mongodb.org/apt/debian"
; ;
*)
msg_error " Unsupported distribution: $DISTRO_ID "
2025-05-05 15:47:43 +02:00
return 1
2025-09-11 12:44:13 +02:00
; ;
esac
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Get currently installed version
2025-09-11 12:44:13 +02:00
local INSTALLED_VERSION = ""
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
INSTALLED_VERSION = $( is_tool_installed "mongodb" 2>/dev/null) || true
2025-06-18 12:07:08 +02:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Scenario 1: Already at target version - just update packages
if [ [ -n " $INSTALLED_VERSION " && " $INSTALLED_VERSION " = = " $MONGO_VERSION " ] ] ; then
msg_info " Update MongoDB $MONGO_VERSION "
2025-10-22 06:25:26 -07:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
ensure_apt_working || return 1
# Perform upgrade with retry logic
upgrade_packages_with_retry "mongodb-org" || {
msg_error "Failed to upgrade MongoDB"
return 1
}
cache_installed_version "mongodb" " $MONGO_VERSION "
msg_ok " Update MongoDB $MONGO_VERSION "
2025-09-11 12:44:13 +02:00
return 0
fi
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Scenario 2: Different version installed - clean upgrade
if [ [ -n " $INSTALLED_VERSION " && " $INSTALLED_VERSION " != " $MONGO_VERSION " ] ] ; then
msg_info " Upgrade MongoDB from $INSTALLED_VERSION to $MONGO_VERSION "
remove_old_tool_version "mongodb"
else
msg_info " Setup MongoDB $MONGO_VERSION "
2025-09-11 12:44:13 +02:00
fi
2025-10-22 06:25:26 -07:00
cleanup_orphaned_sources
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Prepare repository (cleanup + validation)
prepare_repository_setup "mongodb" || {
msg_error "Failed to prepare MongoDB repository"
2025-10-22 17:02:44 +02:00
return 1
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
}
2025-10-22 16:17:20 +02:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Setup repository
manage_tool_repository "mongodb" " $MONGO_VERSION " " $MONGO_BASE_URL " \
" https://www.mongodb.org/static/pgp/server- ${ MONGO_VERSION } .asc " || {
msg_error "Failed to setup MongoDB repository"
2025-10-22 06:25:26 -07:00
return 1
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
}
2025-10-22 06:25:26 -07:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Wait for repo to settle
2025-10-22 06:25:26 -07:00
$STD apt update || {
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
msg_error " APT update failed — invalid MongoDB repo for ${ DISTRO_ID } - ${ DISTRO_CODENAME } ? "
2025-09-11 12:44:13 +02:00
return 1
}
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Install MongoDB with retry logic
install_packages_with_retry "mongodb-org" || {
2025-10-22 06:25:26 -07:00
msg_error "Failed to install MongoDB packages"
return 1
}
2025-09-11 12:44:13 +02:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
if ! command -v mongod >/dev/null 2>& 1; then
msg_error "MongoDB binary not found after installation"
return 1
fi
2025-09-11 12:44:13 +02:00
mkdir -p /var/lib/mongodb
chown -R mongodb:mongodb /var/lib/mongodb
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
$STD systemctl enable mongod || {
msg_warn "Failed to enable mongod service"
}
2025-10-22 06:25:26 -07:00
safe_service_restart mongod
2025-10-22 16:17:20 +02:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Verify MongoDB version
local INSTALLED_VERSION
INSTALLED_VERSION = $( mongod --version 2>/dev/null | grep -oP 'db version v\K[0-9]+\.[0-9]+' | head -n1 || echo "0.0" )
verify_tool_version "MongoDB" " $MONGO_VERSION " " $INSTALLED_VERSION " || true
cache_installed_version "mongodb" " $MONGO_VERSION "
2025-09-11 12:44:13 +02:00
msg_ok " Setup MongoDB $MONGO_VERSION "
2025-04-28 15:25:10 +02:00
}
2025-05-15 15:18:41 +02:00
# ------------------------------------------------------------------------------
2025-09-11 12:44:13 +02:00
# Installs or upgrades MySQL and configures APT repo.
2025-05-15 15:18:41 +02:00
#
# Description:
2025-09-11 12:44:13 +02:00
# - Detects existing MySQL installation
# - Purges conflicting packages before installation
# - Supports clean upgrade
2025-10-22 06:25:26 -07:00
# - Handles Debian Trixie libaio1t64 transition
2025-09-11 12:44:13 +02:00
#
# Variables:
# MYSQL_VERSION - MySQL version to install (e.g. 5.7, 8.0) (default: 8.0)
2025-05-15 15:18:41 +02:00
# ------------------------------------------------------------------------------
2025-09-11 12:44:13 +02:00
function setup_mysql( ) {
local MYSQL_VERSION = " ${ MYSQL_VERSION :- 8 .0 } "
2025-10-22 06:25:26 -07:00
local DISTRO_ID DISTRO_CODENAME
DISTRO_ID = $( awk -F= '/^ID=/{print $2}' /etc/os-release | tr -d '"' )
DISTRO_CODENAME = $( awk -F= '/^VERSION_CODENAME=/{print $2}' /etc/os-release)
2025-04-28 15:25:10 +02:00
2026-01-12 08:48:36 +01:00
# Ensure non-interactive mode for all apt operations
export DEBIAN_FRONTEND = noninteractive
export NEEDRESTART_MODE = a
export NEEDRESTART_SUSPEND = 1
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Get currently installed version
local CURRENT_VERSION = ""
CURRENT_VERSION = $( is_tool_installed "mysql" 2>/dev/null) || true
# Scenario 1: Already at target version - just update packages
if [ [ -n " $CURRENT_VERSION " && " $CURRENT_VERSION " = = " $MYSQL_VERSION " ] ] ; then
msg_info " Update MySQL $MYSQL_VERSION "
ensure_apt_working || return 1
# Perform upgrade with retry logic (non-fatal if fails)
upgrade_packages_with_retry "mysql-server" "mysql-client" || true
cache_installed_version "mysql" " $MYSQL_VERSION "
msg_ok " Update MySQL $MYSQL_VERSION "
return 0
2025-09-11 12:44:13 +02:00
fi
2025-04-28 15:25:10 +02:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Scenario 2: Different version installed - clean upgrade
if [ [ -n " $CURRENT_VERSION " && " $CURRENT_VERSION " != " $MYSQL_VERSION " ] ] ; then
msg_info " Upgrade MySQL from $CURRENT_VERSION to $MYSQL_VERSION "
remove_old_tool_version "mysql"
else
2025-10-22 06:25:26 -07:00
msg_info " Setup MySQL $MYSQL_VERSION "
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
fi
2025-10-22 06:25:26 -07:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Prepare repository (cleanup + validation)
prepare_repository_setup "mysql" || {
msg_error "Failed to prepare MySQL repository"
return 1
}
2025-10-22 06:25:26 -07:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Debian 13+ Fix: MySQL 8.0 incompatible with libaio1t64, use 8.4 LTS
if [ [ " $DISTRO_ID " = = "debian" && " $DISTRO_CODENAME " = ~ ^( trixie| forky| sid) $ ] ] ; then
msg_info " Debian ${ DISTRO_CODENAME } detected → using MySQL 8.4 LTS (libaio1t64 compatible) "
2025-10-22 06:25:26 -07:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
if ! curl -fsSL https://repo.mysql.com/RPM-GPG-KEY-mysql-2023 | gpg --dearmor -o /etc/apt/keyrings/mysql.gpg 2>/dev/null; then
msg_error "Failed to import MySQL GPG key"
return 1
2025-10-22 06:25:26 -07:00
fi
2025-11-07 02:49:16 -08:00
cat >/etc/apt/sources.list.d/mysql.sources <<EOF
2025-10-22 15:42:41 +02:00
Types: deb
URIs: https://repo.mysql.com/apt/debian/
Suites: bookworm
Components: mysql-8.4-lts
2025-11-07 02:49:16 -08:00
Architectures: $( dpkg --print-architecture)
2025-10-22 15:42:41 +02:00
Signed-By: /etc/apt/keyrings/mysql.gpg
2025-10-22 06:25:26 -07:00
EOF
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
$STD apt update || {
msg_error "Failed to update APT for MySQL 8.4 LTS"
2025-10-22 06:25:26 -07:00
return 1
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
}
2025-10-22 06:25:26 -07:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Install with retry logic
if ! install_packages_with_retry "mysql-community-server" "mysql-community-client" ; then
msg_warn "MySQL 8.4 LTS installation failed – falling back to MariaDB"
cleanup_old_repo_files "mysql"
$STD apt update
install_packages_with_retry "mariadb-server" "mariadb-client" || {
msg_error "Failed to install database engine (MySQL/MariaDB fallback)"
return 1
}
msg_ok " Setup Database Engine (MariaDB fallback on Debian ${ DISTRO_CODENAME } ) "
return 0
2025-10-22 06:25:26 -07:00
fi
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
cache_installed_version "mysql" "8.4"
msg_ok " Setup MySQL 8.4 LTS (Debian ${ DISTRO_CODENAME } ) "
return 0
fi
# Standard setup for other distributions
local SUITE
if [ [ " $DISTRO_ID " = = "debian" ] ] ; then
case " $DISTRO_CODENAME " in
bookworm | bullseye) SUITE = " $DISTRO_CODENAME " ; ;
*) SUITE = "bookworm" ; ;
esac
else
SUITE = $( get_fallback_suite " $DISTRO_ID " " $DISTRO_CODENAME " " https://repo.mysql.com/apt/ ${ DISTRO_ID } " )
fi
# Setup repository
manage_tool_repository "mysql" " $MYSQL_VERSION " " https://repo.mysql.com/apt/ ${ DISTRO_ID } " \
"https://repo.mysql.com/RPM-GPG-KEY-mysql-2023" || {
msg_error "Failed to setup MySQL repository"
return 1
}
ensure_apt_working || return 1
# Try multiple package names with retry logic
local mysql_install_success = false
if apt-cache search " ^mysql-server $" 2>/dev/null | grep -q . &&
install_packages_with_retry "mysql-server" "mysql-client" ; then
mysql_install_success = true
elif apt-cache search " ^mysql-community-server $" 2>/dev/null | grep -q . &&
install_packages_with_retry "mysql-community-server" "mysql-community-client" ; then
mysql_install_success = true
elif apt-cache search " ^mysql $" 2>/dev/null | grep -q . &&
install_packages_with_retry "mysql" ; then
mysql_install_success = true
fi
if [ [ " $mysql_install_success " = = false ] ] ; then
msg_error " MySQL ${ MYSQL_VERSION } package not available for suite ${ SUITE } "
return 1
fi
# Verify mysql command is accessible
if ! command -v mysql >/dev/null 2>& 1; then
hash -r
2025-10-22 06:25:26 -07:00
if ! command -v mysql >/dev/null 2>& 1; then
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
msg_error "MySQL installed but mysql command still not found"
return 1
2025-10-22 06:25:26 -07:00
fi
2025-05-05 15:47:43 +02:00
fi
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
cache_installed_version "mysql" " $MYSQL_VERSION "
msg_ok " Setup MySQL $MYSQL_VERSION "
2025-09-11 12:44:13 +02:00
}
2025-04-28 15:25:10 +02:00
2025-09-11 12:44:13 +02:00
# ------------------------------------------------------------------------------
# Installs Node.js and optional global modules.
#
# Description:
# - Installs specified Node.js version using NodeSource APT repo
# - Optionally installs or updates global npm modules
#
# Variables:
Three-tier defaults system | security improvements | error_handler | improved logging | improved container creation | improved architecture (#9540)
* Refactor Core
Refactored misc/alpine-install.func to improve error handling, network checks, and MOTD setup. Added misc/alpine-tools.func and misc/error_handler.func for modular tool installation and error management. Enhanced misc/api.func with detailed exit code explanations and telemetry functions. Updated misc/core.func for better initialization, validation, and execution helpers. Removed misc/create_lxc.sh as part of cleanup.
* Delete config-file.func
* Update install.func
* Refactor stop_all_services function and variable names
Refactor service stopping logic and improve variable handling
* Refactor installation script and update copyright
Updated copyright information and adjusted package installation commands. Enhanced IPv6 disabling logic and improved container customization process.
* Update install.func
* Update license comment format in install.func
* Refactor IPv6 handling and enhance MOTD and SSH
Refactor IPv6 handling and update OS function. Enhance MOTD with additional details and configure SSH settings.
* big core refactor
* Enhance IPv6 configuration menu options
Updated IPv6 Address Management menu options for clarity and added a new option for fully disabling IPv6.
* Update default Node.js version to 24 LTS
* Update misc/alpine-tools.func
Co-authored-by: Michel Roegl-Brunner <73236783+michelroegl-brunner@users.noreply.github.com>
* indention
* remove debugf and duplicate codes
* Update whiptail backtitles and error codes
Removed '[dev]' from whiptail --backtitle strings for consistency. Refactored custom exit codes in build.func and error_handler.func: updated Proxmox error codes, shifted MySQL/MariaDB codes to 260-263, and removed unused MongoDB code. Updated error descriptions to match new codes.
* comments
* Refactor error handling and clean up debug comments
Standardized bash variable checks, removed unnecessary debug and commented code, and clarified error handling logic in container build and setup scripts. These changes improve code readability and maintainability without altering functional behavior.
* Update build.func
* feat: Improve LXC network checks and LINSTOR storage handling
Enhanced LXC container network setup to check for both IPv4 and IPv6 addresses, added connectivity (ping) tests, and provided troubleshooting tips on failure. Updated storage validation to support LINSTOR, including cluster connectivity checks and special handling for LINSTOR template storage.
---------
Co-authored-by: Michel Roegl-Brunner <73236783+michelroegl-brunner@users.noreply.github.com>
2025-12-04 07:52:18 +01:00
# NODE_VERSION - Node.js version to install (default: 24 LTS)
2025-09-11 12:44:13 +02:00
# NODE_MODULE - Comma-separated list of global modules (e.g. "yarn,@vue/cli@5.0.0")
# ------------------------------------------------------------------------------
2025-04-28 15:25:10 +02:00
2025-09-11 12:44:13 +02:00
function setup_nodejs( ) {
Three-tier defaults system | security improvements | error_handler | improved logging | improved container creation | improved architecture (#9540)
* Refactor Core
Refactored misc/alpine-install.func to improve error handling, network checks, and MOTD setup. Added misc/alpine-tools.func and misc/error_handler.func for modular tool installation and error management. Enhanced misc/api.func with detailed exit code explanations and telemetry functions. Updated misc/core.func for better initialization, validation, and execution helpers. Removed misc/create_lxc.sh as part of cleanup.
* Delete config-file.func
* Update install.func
* Refactor stop_all_services function and variable names
Refactor service stopping logic and improve variable handling
* Refactor installation script and update copyright
Updated copyright information and adjusted package installation commands. Enhanced IPv6 disabling logic and improved container customization process.
* Update install.func
* Update license comment format in install.func
* Refactor IPv6 handling and enhance MOTD and SSH
Refactor IPv6 handling and update OS function. Enhance MOTD with additional details and configure SSH settings.
* big core refactor
* Enhance IPv6 configuration menu options
Updated IPv6 Address Management menu options for clarity and added a new option for fully disabling IPv6.
* Update default Node.js version to 24 LTS
* Update misc/alpine-tools.func
Co-authored-by: Michel Roegl-Brunner <73236783+michelroegl-brunner@users.noreply.github.com>
* indention
* remove debugf and duplicate codes
* Update whiptail backtitles and error codes
Removed '[dev]' from whiptail --backtitle strings for consistency. Refactored custom exit codes in build.func and error_handler.func: updated Proxmox error codes, shifted MySQL/MariaDB codes to 260-263, and removed unused MongoDB code. Updated error descriptions to match new codes.
* comments
* Refactor error handling and clean up debug comments
Standardized bash variable checks, removed unnecessary debug and commented code, and clarified error handling logic in container build and setup scripts. These changes improve code readability and maintainability without altering functional behavior.
* Update build.func
* feat: Improve LXC network checks and LINSTOR storage handling
Enhanced LXC container network setup to check for both IPv4 and IPv6 addresses, added connectivity (ping) tests, and provided troubleshooting tips on failure. Updated storage validation to support LINSTOR, including cluster connectivity checks and special handling for LINSTOR template storage.
---------
Co-authored-by: Michel Roegl-Brunner <73236783+michelroegl-brunner@users.noreply.github.com>
2025-12-04 07:52:18 +01:00
local NODE_VERSION = " ${ NODE_VERSION :- 24 } "
2025-09-11 12:44:13 +02:00
local NODE_MODULE = " ${ NODE_MODULE :- } "
2025-04-28 15:25:10 +02:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# ALWAYS clean up legacy installations first (nvm, etc.) to prevent conflicts
cleanup_legacy_install "nodejs"
# Get currently installed version
local CURRENT_NODE_VERSION = ""
CURRENT_NODE_VERSION = $( is_tool_installed "nodejs" 2>/dev/null) || true
2025-04-28 15:25:10 +02:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Ensure jq is available for JSON parsing
2025-10-22 16:38:58 +02:00
if ! command -v jq & >/dev/null; then
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
$STD apt update
$STD apt install -y jq || {
2025-10-22 16:38:58 +02:00
msg_error "Failed to install jq"
return 1
}
fi
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Scenario 1: Already installed at target version - just update packages/modules
if [ [ -n " $CURRENT_NODE_VERSION " && " $CURRENT_NODE_VERSION " = = " $NODE_VERSION " ] ] ; then
msg_info " Update Node.js $NODE_VERSION "
2025-04-28 15:25:10 +02:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
ensure_apt_working || return 1
2025-04-28 15:25:10 +02:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Just update npm to latest
$STD npm install -g npm@latest 2>/dev/null || true
2025-04-28 15:25:10 +02:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
cache_installed_version "nodejs" " $NODE_VERSION "
msg_ok " Update Node.js $NODE_VERSION "
else
# Scenario 2: Different version installed - clean upgrade
if [ [ -n " $CURRENT_NODE_VERSION " && " $CURRENT_NODE_VERSION " != " $NODE_VERSION " ] ] ; then
msg_info " Upgrade Node.js from $CURRENT_NODE_VERSION to $NODE_VERSION "
remove_old_tool_version "nodejs"
else
msg_info " Setup Node.js $NODE_VERSION "
fi
2025-04-28 15:25:10 +02:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Remove ALL Debian nodejs packages BEFORE adding NodeSource repo
if dpkg -l 2>/dev/null | grep -qE "^ii.*(nodejs|libnode|node-cjs|node-acorn|node-balanced|node-brace|node-minimatch|node-undici|node-xtend|node-corepack)" ; then
msg_info "Removing Debian-packaged Node.js and dependencies"
$STD apt purge -y nodejs nodejs-doc libnode* node-* 2>/dev/null || true
$STD apt autoremove -y 2>/dev/null || true
$STD apt clean 2>/dev/null || true
2025-09-11 12:44:13 +02:00
fi
2025-04-28 15:25:10 +02:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Remove any APT pinning (not needed)
rm -f /etc/apt/preferences.d/nodesource 2>/dev/null || true
# Prepare repository (cleanup + validation)
prepare_repository_setup "nodesource" || {
msg_error "Failed to prepare Node.js repository"
return 1
}
# Setup NodeSource repository
manage_tool_repository "nodejs" " $NODE_VERSION " " https://deb.nodesource.com/node_ ${ NODE_VERSION } .x " "https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key" || {
msg_error "Failed to setup Node.js repository"
return 1
}
Three-tier defaults system | security improvements | error_handler | improved logging | improved container creation | improved architecture (#9540)
* Refactor Core
Refactored misc/alpine-install.func to improve error handling, network checks, and MOTD setup. Added misc/alpine-tools.func and misc/error_handler.func for modular tool installation and error management. Enhanced misc/api.func with detailed exit code explanations and telemetry functions. Updated misc/core.func for better initialization, validation, and execution helpers. Removed misc/create_lxc.sh as part of cleanup.
* Delete config-file.func
* Update install.func
* Refactor stop_all_services function and variable names
Refactor service stopping logic and improve variable handling
* Refactor installation script and update copyright
Updated copyright information and adjusted package installation commands. Enhanced IPv6 disabling logic and improved container customization process.
* Update install.func
* Update license comment format in install.func
* Refactor IPv6 handling and enhance MOTD and SSH
Refactor IPv6 handling and update OS function. Enhance MOTD with additional details and configure SSH settings.
* big core refactor
* Enhance IPv6 configuration menu options
Updated IPv6 Address Management menu options for clarity and added a new option for fully disabling IPv6.
* Update default Node.js version to 24 LTS
* Update misc/alpine-tools.func
Co-authored-by: Michel Roegl-Brunner <73236783+michelroegl-brunner@users.noreply.github.com>
* indention
* remove debugf and duplicate codes
* Update whiptail backtitles and error codes
Removed '[dev]' from whiptail --backtitle strings for consistency. Refactored custom exit codes in build.func and error_handler.func: updated Proxmox error codes, shifted MySQL/MariaDB codes to 260-263, and removed unused MongoDB code. Updated error descriptions to match new codes.
* comments
* Refactor error handling and clean up debug comments
Standardized bash variable checks, removed unnecessary debug and commented code, and clarified error handling logic in container build and setup scripts. These changes improve code readability and maintainability without altering functional behavior.
* Update build.func
* feat: Improve LXC network checks and LINSTOR storage handling
Enhanced LXC container network setup to check for both IPv4 and IPv6 addresses, added connectivity (ping) tests, and provided troubleshooting tips on failure. Updated storage validation to support LINSTOR, including cluster connectivity checks and special handling for LINSTOR template storage.
---------
Co-authored-by: Michel Roegl-Brunner <73236783+michelroegl-brunner@users.noreply.github.com>
2025-12-04 07:52:18 +01:00
# Force APT cache refresh after repository setup
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
$STD apt update
ensure_dependencies curl ca-certificates gnupg
install_packages_with_retry "nodejs" || {
2025-10-22 16:38:58 +02:00
msg_error " Failed to install Node.js ${ NODE_VERSION } from NodeSource "
return 1
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
}
# Verify Node.js was installed correctly
if ! command -v node >/dev/null 2>& 1; then
msg_error "Node.js binary not found after installation"
return 1
2025-10-22 16:21:01 +02:00
fi
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
local INSTALLED_NODE_VERSION
INSTALLED_NODE_VERSION = $( node -v 2>/dev/null | grep -oP '^v\K[0-9]+' || echo "0" )
verify_tool_version "Node.js" " $NODE_VERSION " " $INSTALLED_NODE_VERSION " || true
# Verify npm is available (should come with NodeSource nodejs)
if ! command -v npm >/dev/null 2>& 1; then
msg_error "npm not found after Node.js installation - repository issue?"
return 1
fi
# Update to latest npm (with version check to avoid incompatibility)
local NPM_VERSION
NPM_VERSION = $( npm -v 2>/dev/null || echo "0" )
if [ [ " $NPM_VERSION " != "0" ] ] ; then
$STD npm install -g npm@latest 2>/dev/null || {
msg_warn " Failed to update npm to latest version (continuing with bundled npm $NPM_VERSION ) "
}
fi
2025-10-22 06:25:26 -07:00
cache_installed_version "nodejs" " $NODE_VERSION "
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
msg_ok " Setup Node.js $NODE_VERSION "
2025-09-11 12:44:13 +02:00
fi
2025-04-28 15:25:10 +02:00
2025-09-11 12:44:13 +02:00
export NODE_OPTIONS = "--max-old-space-size=4096"
2025-10-22 16:38:58 +02:00
# Ensure valid working directory for npm (avoids uv_cwd error)
if [ [ ! -d /opt ] ] ; then
mkdir -p /opt
fi
cd /opt || {
msg_error "Failed to set safe working directory before npm install"
2025-10-22 06:25:26 -07:00
return 1
2025-09-11 12:44:13 +02:00
}
2025-04-28 15:25:10 +02:00
2025-10-22 16:38:58 +02:00
# Install global Node modules
2025-09-11 12:44:13 +02:00
if [ [ -n " $NODE_MODULE " ] ] ; then
IFS = ',' read -ra MODULES <<< " $NODE_MODULE "
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
local failed_modules = 0
2025-09-11 12:44:13 +02:00
for mod in " ${ MODULES [@] } " ; do
local MODULE_NAME MODULE_REQ_VERSION MODULE_INSTALLED_VERSION
if [ [ " $mod " = = @*/*@* ] ] ; then
2025-10-22 16:38:58 +02:00
# Scoped package with version, e.g. @vue/cli-service@latest
2025-09-11 12:44:13 +02:00
MODULE_NAME = " ${ mod %@* } "
MODULE_REQ_VERSION = " ${ mod ##*@ } "
elif [ [ " $mod " = = *"@" * ] ] ; then
2025-10-22 16:38:58 +02:00
# Unscoped package with version, e.g. yarn@latest
2025-09-11 12:44:13 +02:00
MODULE_NAME = " ${ mod %@* } "
MODULE_REQ_VERSION = " ${ mod ##*@ } "
else
2025-10-22 16:38:58 +02:00
# No version specified
2025-09-11 12:44:13 +02:00
MODULE_NAME = " $mod "
MODULE_REQ_VERSION = "latest"
fi
2025-05-05 15:47:43 +02:00
2025-10-22 16:38:58 +02:00
# Check if the module is already installed
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
if $STD npm list -g --depth= 0 " $MODULE_NAME " 2>& 1 | grep -q " $MODULE_NAME @ " ; then
2025-12-18 18:38:08 +01:00
MODULE_INSTALLED_VERSION = " $( npm list -g --depth= 0 " $MODULE_NAME " 2>& 1 | grep " $MODULE_NAME @ " | awk -F@ '{print $2}' 2>/dev/null | tr -d '[:space:]' || echo '' ) "
2025-09-11 12:44:13 +02:00
if [ [ " $MODULE_REQ_VERSION " != "latest" && " $MODULE_REQ_VERSION " != " $MODULE_INSTALLED_VERSION " ] ] ; then
2025-10-22 16:38:58 +02:00
msg_info " Updating $MODULE_NAME from v $MODULE_INSTALLED_VERSION to v $MODULE_REQ_VERSION "
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
if ! $STD npm install -g " ${ MODULE_NAME } @ ${ MODULE_REQ_VERSION } " 2>/dev/null; then
msg_warn " Failed to update $MODULE_NAME to version $MODULE_REQ_VERSION "
2026-01-06 20:32:15 +01:00
( ( failed_modules++) ) || true
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
continue
2025-10-22 16:38:58 +02:00
fi
2025-09-11 12:44:13 +02:00
elif [ [ " $MODULE_REQ_VERSION " = = "latest" ] ] ; then
2025-10-22 16:38:58 +02:00
msg_info " Updating $MODULE_NAME to latest version "
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
if ! $STD npm install -g " ${ MODULE_NAME } @latest " 2>/dev/null; then
msg_warn " Failed to update $MODULE_NAME to latest version "
2026-01-06 20:32:15 +01:00
( ( failed_modules++) ) || true
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
continue
2025-10-22 16:38:58 +02:00
fi
2025-04-28 15:25:10 +02:00
fi
2025-09-11 12:44:13 +02:00
else
2025-10-22 16:38:58 +02:00
msg_info " Installing $MODULE_NAME @ $MODULE_REQ_VERSION "
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
if ! $STD npm install -g " ${ MODULE_NAME } @ ${ MODULE_REQ_VERSION } " 2>/dev/null; then
msg_warn " Failed to install $MODULE_NAME @ $MODULE_REQ_VERSION "
2026-01-06 20:32:15 +01:00
( ( failed_modules++) ) || true
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
continue
2025-10-22 16:38:58 +02:00
fi
2025-09-11 12:44:13 +02:00
fi
done
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
if [ [ $failed_modules -eq 0 ] ] ; then
msg_ok " Installed Node.js modules: $NODE_MODULE "
else
msg_warn " Installed Node.js modules with $failed_modules failure(s): $NODE_MODULE "
fi
2025-05-05 15:47:43 +02:00
fi
2025-04-28 15:25:10 +02:00
}
2025-04-29 16:04:29 +02:00
2025-05-15 15:18:41 +02:00
# ------------------------------------------------------------------------------
2025-09-11 12:44:13 +02:00
# Installs PHP with selected modules and configures Apache/FPM support.
2025-05-15 15:18:41 +02:00
#
2025-09-11 12:44:13 +02:00
# Description:
# - Adds Sury PHP repo if needed
# - Installs default and user-defined modules
# - Patches php.ini for CLI, Apache, and FPM as needed
fix(php): improve module handling and prevent installation failures (#11358)
Changes to setup_php():
- Add version detection for PHP 8.5+ built-in opcache
- Define BUILTIN_MODULES list for modules included in php-common
(ctype, fileinfo, iconv, tokenizer, phar, posix, etc.)
- Filter out built-in modules before attempting installation
- Verify each package exists via apt-cache before adding to install list
- Skip unavailable packages with informational message instead of error
- Add extended default modules (mysql, sqlite3, pgsql, redis, imagick,
bz2, apcu) to cover ~90% of typical use cases
- Improve error handling with graceful degradation
This prevents installation failures when:
- PHP version has module built into core (e.g., opcache in 8.5+)
- Module is provided by php-common (ctype, fileinfo, etc.)
- Package is renamed or unavailable in specific PHP version
Fixes #11359
2026-01-30 10:29:51 +01:00
# - Handles built-in modules gracefully (e.g., opcache in PHP 8.5+)
# - Skips unavailable packages without failing
2025-09-11 12:44:13 +02:00
#
# Variables:
# PHP_VERSION - PHP version to install (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 - (default: 512M)
# PHP_UPLOAD_MAX_FILESIZE - (default: 128M)
# PHP_POST_MAX_SIZE - (default: 128M)
# PHP_MAX_EXECUTION_TIME - (default: 300)
fix(php): improve module handling and prevent installation failures (#11358)
Changes to setup_php():
- Add version detection for PHP 8.5+ built-in opcache
- Define BUILTIN_MODULES list for modules included in php-common
(ctype, fileinfo, iconv, tokenizer, phar, posix, etc.)
- Filter out built-in modules before attempting installation
- Verify each package exists via apt-cache before adding to install list
- Skip unavailable packages with informational message instead of error
- Add extended default modules (mysql, sqlite3, pgsql, redis, imagick,
bz2, apcu) to cover ~90% of typical use cases
- Improve error handling with graceful degradation
This prevents installation failures when:
- PHP version has module built into core (e.g., opcache in 8.5+)
- Module is provided by php-common (ctype, fileinfo, etc.)
- Package is renamed or unavailable in specific PHP version
Fixes #11359
2026-01-30 10:29:51 +01:00
#
# Notes on modules:
# - Base modules (always installed): bcmath, cli, curl, gd, intl, mbstring,
# readline, xml, zip, common
# - Extended modules (commonly needed): mysql, sqlite3, pgsql, redis,
# imagick, bz2, ldap, soap, imap, gmp, apcu
# - Some modules are built-in depending on PHP version:
# * PHP 8.5+: opcache is built-in (no separate package)
# * All versions: ctype, fileinfo, iconv, tokenizer, phar, posix, etc.
# are part of php-common
# - Unavailable modules are skipped with a warning, not an error
2025-05-15 15:18:41 +02:00
# ------------------------------------------------------------------------------
2025-09-11 12:44:13 +02:00
function setup_php( ) {
local PHP_VERSION = " ${ PHP_VERSION :- 8 .4 } "
local PHP_MODULE = " ${ PHP_MODULE :- } "
local PHP_APACHE = " ${ PHP_APACHE :- NO } "
local PHP_FPM = " ${ PHP_FPM :- NO } "
2025-10-22 06:25:26 -07:00
local DISTRO_ID DISTRO_CODENAME
DISTRO_ID = $( awk -F= '/^ID=/{print $2}' /etc/os-release | tr -d '"' )
DISTRO_CODENAME = $( awk -F= '/^VERSION_CODENAME=/{print $2}' /etc/os-release)
2025-05-05 15:47:43 +02:00
fix(php): improve module handling and prevent installation failures (#11358)
Changes to setup_php():
- Add version detection for PHP 8.5+ built-in opcache
- Define BUILTIN_MODULES list for modules included in php-common
(ctype, fileinfo, iconv, tokenizer, phar, posix, etc.)
- Filter out built-in modules before attempting installation
- Verify each package exists via apt-cache before adding to install list
- Skip unavailable packages with informational message instead of error
- Add extended default modules (mysql, sqlite3, pgsql, redis, imagick,
bz2, apcu) to cover ~90% of typical use cases
- Improve error handling with graceful degradation
This prevents installation failures when:
- PHP version has module built into core (e.g., opcache in 8.5+)
- Module is provided by php-common (ctype, fileinfo, etc.)
- Package is renamed or unavailable in specific PHP version
Fixes #11359
2026-01-30 10:29:51 +01:00
# Parse version for compatibility checks
local PHP_MAJOR = " ${ PHP_VERSION %%.* } "
local PHP_MINOR = " ${ PHP_VERSION #*. } "
PHP_MINOR = " ${ PHP_MINOR %%.* } "
# Modules that are ALWAYS part of php-common (no separate package needed)
# These are either built-in or virtual packages provided by php-common
local BUILTIN_MODULES = "calendar,ctype,exif,ffi,fileinfo,ftp,gettext,iconv,pdo,phar,posix,shmop,sockets,sysvmsg,sysvsem,sysvshm,tokenizer"
# Modules that became built-in in specific PHP versions
# PHP 8.5+: opcache is now part of the core
local BUILTIN_85 = ""
if [ [ " $PHP_MAJOR " -gt 8 ] ] || [ [ " $PHP_MAJOR " -eq 8 && " $PHP_MINOR " -ge 5 ] ] ; then
BUILTIN_85 = "opcache"
fi
# Base modules - essential for most PHP applications
# Note: 'common' provides many built-in extensions
refactor(php): remove redundant PHP_MODULE entries (#11362)
- Add dom and gmp to BASE_MODULES in setup_php()
- Remove modules already covered by BASE_MODULES (cli,common,bcmath,curl,dom,gd,gmp,intl,mbstring,readline,xml,zip)
- Remove modules already covered by EXTENDED_MODULES (mysql,sqlite3,pgsql,redis,imagick,bz2,apcu)
- Remove modules already covered by BUILTIN (ctype,exif,ffi,fileinfo,gettext,iconv,pdo,tokenizer)
- Affected: 31 install scripts, 12 ct scripts
2026-01-30 13:05:05 +01:00
local BASE_MODULES = "cli,common,bcmath,curl,dom,gd,gmp,intl,mbstring,readline,xml,zip"
fix(php): improve module handling and prevent installation failures (#11358)
Changes to setup_php():
- Add version detection for PHP 8.5+ built-in opcache
- Define BUILTIN_MODULES list for modules included in php-common
(ctype, fileinfo, iconv, tokenizer, phar, posix, etc.)
- Filter out built-in modules before attempting installation
- Verify each package exists via apt-cache before adding to install list
- Skip unavailable packages with informational message instead of error
- Add extended default modules (mysql, sqlite3, pgsql, redis, imagick,
bz2, apcu) to cover ~90% of typical use cases
- Improve error handling with graceful degradation
This prevents installation failures when:
- PHP version has module built into core (e.g., opcache in 8.5+)
- Module is provided by php-common (ctype, fileinfo, etc.)
- Package is renamed or unavailable in specific PHP version
Fixes #11359
2026-01-30 10:29:51 +01:00
# Add opcache only for PHP < 8.5 (it's built-in starting from 8.5)
if [ [ " $PHP_MAJOR " -lt 8 ] ] || [ [ " $PHP_MAJOR " -eq 8 && " $PHP_MINOR " -lt 5 ] ] ; then
BASE_MODULES = " ${ BASE_MODULES } ,opcache "
fi
# Extended default modules - commonly needed by web applications
# These cover ~90% of typical use cases without bloat
local EXTENDED_MODULES = "mysql,sqlite3,pgsql,redis,imagick,bz2,apcu"
local COMBINED_MODULES = " ${ BASE_MODULES } , ${ EXTENDED_MODULES } "
2025-04-29 16:04:29 +02:00
2025-09-11 12:44:13 +02:00
local PHP_MEMORY_LIMIT = " ${ PHP_MEMORY_LIMIT :- 512M } "
local PHP_UPLOAD_MAX_FILESIZE = " ${ PHP_UPLOAD_MAX_FILESIZE :- 128M } "
local PHP_POST_MAX_SIZE = " ${ PHP_POST_MAX_SIZE :- 128M } "
local PHP_MAX_EXECUTION_TIME = " ${ PHP_MAX_EXECUTION_TIME :- 300 } "
2025-05-05 15:47:43 +02:00
fix(php): improve module handling and prevent installation failures (#11358)
Changes to setup_php():
- Add version detection for PHP 8.5+ built-in opcache
- Define BUILTIN_MODULES list for modules included in php-common
(ctype, fileinfo, iconv, tokenizer, phar, posix, etc.)
- Filter out built-in modules before attempting installation
- Verify each package exists via apt-cache before adding to install list
- Skip unavailable packages with informational message instead of error
- Add extended default modules (mysql, sqlite3, pgsql, redis, imagick,
bz2, apcu) to cover ~90% of typical use cases
- Improve error handling with graceful degradation
This prevents installation failures when:
- PHP version has module built into core (e.g., opcache in 8.5+)
- Module is provided by php-common (ctype, fileinfo, etc.)
- Package is renamed or unavailable in specific PHP version
Fixes #11359
2026-01-30 10:29:51 +01:00
# Merge with user-defined modules
2025-09-11 12:44:13 +02:00
if [ [ -n " $PHP_MODULE " ] ] ; then
fix(php): improve module handling and prevent installation failures (#11358)
Changes to setup_php():
- Add version detection for PHP 8.5+ built-in opcache
- Define BUILTIN_MODULES list for modules included in php-common
(ctype, fileinfo, iconv, tokenizer, phar, posix, etc.)
- Filter out built-in modules before attempting installation
- Verify each package exists via apt-cache before adding to install list
- Skip unavailable packages with informational message instead of error
- Add extended default modules (mysql, sqlite3, pgsql, redis, imagick,
bz2, apcu) to cover ~90% of typical use cases
- Improve error handling with graceful degradation
This prevents installation failures when:
- PHP version has module built into core (e.g., opcache in 8.5+)
- Module is provided by php-common (ctype, fileinfo, etc.)
- Package is renamed or unavailable in specific PHP version
Fixes #11359
2026-01-30 10:29:51 +01:00
COMBINED_MODULES = " ${ COMBINED_MODULES } , ${ PHP_MODULE } "
2025-05-05 15:47:43 +02:00
fi
2025-06-18 12:07:08 +02:00
fix(php): improve module handling and prevent installation failures (#11358)
Changes to setup_php():
- Add version detection for PHP 8.5+ built-in opcache
- Define BUILTIN_MODULES list for modules included in php-common
(ctype, fileinfo, iconv, tokenizer, phar, posix, etc.)
- Filter out built-in modules before attempting installation
- Verify each package exists via apt-cache before adding to install list
- Skip unavailable packages with informational message instead of error
- Add extended default modules (mysql, sqlite3, pgsql, redis, imagick,
bz2, apcu) to cover ~90% of typical use cases
- Improve error handling with graceful degradation
This prevents installation failures when:
- PHP version has module built into core (e.g., opcache in 8.5+)
- Module is provided by php-common (ctype, fileinfo, etc.)
- Package is renamed or unavailable in specific PHP version
Fixes #11359
2026-01-30 10:29:51 +01:00
# Filter out built-in modules (they don't have separate packages)
local FILTERED_MODULES = ""
IFS = ',' read -ra ALL_MODULES <<< " $COMBINED_MODULES "
for mod in " ${ ALL_MODULES [@] } " ; do
mod = $( echo " $mod " | tr -d '[:space:]' )
[ [ -z " $mod " ] ] && continue
# Skip if it's a known built-in module
if echo " , $BUILTIN_MODULES , $BUILTIN_85 , " | grep -qi " , $mod , " ; then
continue
fi
# Add to filtered list
if [ [ -z " $FILTERED_MODULES " ] ] ; then
FILTERED_MODULES = " $mod "
else
FILTERED_MODULES = " ${ FILTERED_MODULES } , $mod "
fi
done
2025-09-11 12:44:13 +02:00
# Deduplicate
fix(php): improve module handling and prevent installation failures (#11358)
Changes to setup_php():
- Add version detection for PHP 8.5+ built-in opcache
- Define BUILTIN_MODULES list for modules included in php-common
(ctype, fileinfo, iconv, tokenizer, phar, posix, etc.)
- Filter out built-in modules before attempting installation
- Verify each package exists via apt-cache before adding to install list
- Skip unavailable packages with informational message instead of error
- Add extended default modules (mysql, sqlite3, pgsql, redis, imagick,
bz2, apcu) to cover ~90% of typical use cases
- Improve error handling with graceful degradation
This prevents installation failures when:
- PHP version has module built into core (e.g., opcache in 8.5+)
- Module is provided by php-common (ctype, fileinfo, etc.)
- Package is renamed or unavailable in specific PHP version
Fixes #11359
2026-01-30 10:29:51 +01:00
COMBINED_MODULES = $( echo " $FILTERED_MODULES " | tr ',' '\n' | awk '!seen[$0]++' | paste -sd, -)
2025-05-05 15:47:43 +02:00
2025-09-11 12:44:13 +02:00
# Get current PHP-CLI version
local CURRENT_PHP = ""
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
CURRENT_PHP = $( is_tool_installed "php" 2>/dev/null) || true
2025-06-18 12:07:08 +02:00
Three-tier defaults system | security improvements | error_handler | improved logging | improved container creation | improved architecture (#9540)
* Refactor Core
Refactored misc/alpine-install.func to improve error handling, network checks, and MOTD setup. Added misc/alpine-tools.func and misc/error_handler.func for modular tool installation and error management. Enhanced misc/api.func with detailed exit code explanations and telemetry functions. Updated misc/core.func for better initialization, validation, and execution helpers. Removed misc/create_lxc.sh as part of cleanup.
* Delete config-file.func
* Update install.func
* Refactor stop_all_services function and variable names
Refactor service stopping logic and improve variable handling
* Refactor installation script and update copyright
Updated copyright information and adjusted package installation commands. Enhanced IPv6 disabling logic and improved container customization process.
* Update install.func
* Update license comment format in install.func
* Refactor IPv6 handling and enhance MOTD and SSH
Refactor IPv6 handling and update OS function. Enhance MOTD with additional details and configure SSH settings.
* big core refactor
* Enhance IPv6 configuration menu options
Updated IPv6 Address Management menu options for clarity and added a new option for fully disabling IPv6.
* Update default Node.js version to 24 LTS
* Update misc/alpine-tools.func
Co-authored-by: Michel Roegl-Brunner <73236783+michelroegl-brunner@users.noreply.github.com>
* indention
* remove debugf and duplicate codes
* Update whiptail backtitles and error codes
Removed '[dev]' from whiptail --backtitle strings for consistency. Refactored custom exit codes in build.func and error_handler.func: updated Proxmox error codes, shifted MySQL/MariaDB codes to 260-263, and removed unused MongoDB code. Updated error descriptions to match new codes.
* comments
* Refactor error handling and clean up debug comments
Standardized bash variable checks, removed unnecessary debug and commented code, and clarified error handling logic in container build and setup scripts. These changes improve code readability and maintainability without altering functional behavior.
* Update build.func
* feat: Improve LXC network checks and LINSTOR storage handling
Enhanced LXC container network setup to check for both IPv4 and IPv6 addresses, added connectivity (ping) tests, and provided troubleshooting tips on failure. Updated storage validation to support LINSTOR, including cluster connectivity checks and special handling for LINSTOR template storage.
---------
Co-authored-by: Michel Roegl-Brunner <73236783+michelroegl-brunner@users.noreply.github.com>
2025-12-04 07:52:18 +01:00
# Remove conflicting PHP version before pinning
2025-11-22 13:08:30 +01:00
if [ [ -n " $CURRENT_PHP " && " $CURRENT_PHP " != " $PHP_VERSION " ] ] ; then
msg_info " Removing conflicting PHP ${ CURRENT_PHP } (need ${ PHP_VERSION } ) "
stop_all_services "php.*-fpm"
Three-tier defaults system | security improvements | error_handler | improved logging | improved container creation | improved architecture (#9540)
* Refactor Core
Refactored misc/alpine-install.func to improve error handling, network checks, and MOTD setup. Added misc/alpine-tools.func and misc/error_handler.func for modular tool installation and error management. Enhanced misc/api.func with detailed exit code explanations and telemetry functions. Updated misc/core.func for better initialization, validation, and execution helpers. Removed misc/create_lxc.sh as part of cleanup.
* Delete config-file.func
* Update install.func
* Refactor stop_all_services function and variable names
Refactor service stopping logic and improve variable handling
* Refactor installation script and update copyright
Updated copyright information and adjusted package installation commands. Enhanced IPv6 disabling logic and improved container customization process.
* Update install.func
* Update license comment format in install.func
* Refactor IPv6 handling and enhance MOTD and SSH
Refactor IPv6 handling and update OS function. Enhance MOTD with additional details and configure SSH settings.
* big core refactor
* Enhance IPv6 configuration menu options
Updated IPv6 Address Management menu options for clarity and added a new option for fully disabling IPv6.
* Update default Node.js version to 24 LTS
* Update misc/alpine-tools.func
Co-authored-by: Michel Roegl-Brunner <73236783+michelroegl-brunner@users.noreply.github.com>
* indention
* remove debugf and duplicate codes
* Update whiptail backtitles and error codes
Removed '[dev]' from whiptail --backtitle strings for consistency. Refactored custom exit codes in build.func and error_handler.func: updated Proxmox error codes, shifted MySQL/MariaDB codes to 260-263, and removed unused MongoDB code. Updated error descriptions to match new codes.
* comments
* Refactor error handling and clean up debug comments
Standardized bash variable checks, removed unnecessary debug and commented code, and clarified error handling logic in container build and setup scripts. These changes improve code readability and maintainability without altering functional behavior.
* Update build.func
* feat: Improve LXC network checks and LINSTOR storage handling
Enhanced LXC container network setup to check for both IPv4 and IPv6 addresses, added connectivity (ping) tests, and provided troubleshooting tips on failure. Updated storage validation to support LINSTOR, including cluster connectivity checks and special handling for LINSTOR template storage.
---------
Co-authored-by: Michel Roegl-Brunner <73236783+michelroegl-brunner@users.noreply.github.com>
2025-12-04 07:52:18 +01:00
$STD apt purge -y "php*" 2>/dev/null || true
$STD apt autoremove -y 2>/dev/null || true
2025-11-22 13:08:30 +01:00
fi
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
2025-11-22 13:08:30 +01:00
# NOW create pinning for the desired version
mkdir -p /etc/apt/preferences.d
cat <<EOF >/etc/apt/preferences.d/php-pin
2025-11-22 13:02:53 +01:00
Package: php${ PHP_VERSION } *
Pin: version ${ PHP_VERSION } .*
Pin-Priority: 1001
Package: php[ 0-9] .*
Pin: release o = packages.sury.org-php
Pin-Priority: -1
EOF
2025-11-22 13:08:30 +01:00
# Setup repository
prepare_repository_setup "php" "deb.sury.org-php" || {
msg_error "Failed to prepare PHP repository"
return 1
}
2025-11-22 13:02:53 +01:00
2026-01-21 15:39:15 +01:00
# Use different repository based on OS
if [ [ " $DISTRO_ID " = = "ubuntu" ] ] ; then
# Ubuntu: Use ondrej/php PPA
msg_info "Adding ondrej/php PPA for Ubuntu"
$STD apt install -y software-properties-common
2026-01-28 11:09:30 +01:00
# Don't use $STD for add-apt-repository as it uses background processes
add-apt-repository -y ppa:ondrej/php >>" $( get_active_logfile) " 2>& 1
2026-01-21 15:39:15 +01:00
else
# Debian: Use Sury repository
manage_tool_repository "php" " $PHP_VERSION " "" "https://packages.sury.org/debsuryorg-archive-keyring.deb" || {
msg_error "Failed to setup PHP repository"
return 1
}
fi
2025-11-22 13:08:30 +01:00
ensure_apt_working || return 1
Three-tier defaults system | security improvements | error_handler | improved logging | improved container creation | improved architecture (#9540)
* Refactor Core
Refactored misc/alpine-install.func to improve error handling, network checks, and MOTD setup. Added misc/alpine-tools.func and misc/error_handler.func for modular tool installation and error management. Enhanced misc/api.func with detailed exit code explanations and telemetry functions. Updated misc/core.func for better initialization, validation, and execution helpers. Removed misc/create_lxc.sh as part of cleanup.
* Delete config-file.func
* Update install.func
* Refactor stop_all_services function and variable names
Refactor service stopping logic and improve variable handling
* Refactor installation script and update copyright
Updated copyright information and adjusted package installation commands. Enhanced IPv6 disabling logic and improved container customization process.
* Update install.func
* Update license comment format in install.func
* Refactor IPv6 handling and enhance MOTD and SSH
Refactor IPv6 handling and update OS function. Enhance MOTD with additional details and configure SSH settings.
* big core refactor
* Enhance IPv6 configuration menu options
Updated IPv6 Address Management menu options for clarity and added a new option for fully disabling IPv6.
* Update default Node.js version to 24 LTS
* Update misc/alpine-tools.func
Co-authored-by: Michel Roegl-Brunner <73236783+michelroegl-brunner@users.noreply.github.com>
* indention
* remove debugf and duplicate codes
* Update whiptail backtitles and error codes
Removed '[dev]' from whiptail --backtitle strings for consistency. Refactored custom exit codes in build.func and error_handler.func: updated Proxmox error codes, shifted MySQL/MariaDB codes to 260-263, and removed unused MongoDB code. Updated error descriptions to match new codes.
* comments
* Refactor error handling and clean up debug comments
Standardized bash variable checks, removed unnecessary debug and commented code, and clarified error handling logic in container build and setup scripts. These changes improve code readability and maintainability without altering functional behavior.
* Update build.func
* feat: Improve LXC network checks and LINSTOR storage handling
Enhanced LXC container network setup to check for both IPv4 and IPv6 addresses, added connectivity (ping) tests, and provided troubleshooting tips on failure. Updated storage validation to support LINSTOR, including cluster connectivity checks and special handling for LINSTOR template storage.
---------
Co-authored-by: Michel Roegl-Brunner <73236783+michelroegl-brunner@users.noreply.github.com>
2025-12-04 07:52:18 +01:00
$STD apt update
2025-05-05 15:47:43 +02:00
2025-11-22 12:52:47 +01:00
# Get available PHP version from repository
local AVAILABLE_PHP_VERSION = ""
2025-12-18 18:38:08 +01:00
AVAILABLE_PHP_VERSION = $( apt-cache show " php ${ PHP_VERSION } " 2>/dev/null | grep -m1 "^Version:" | awk '{print $2}' 2>/dev/null | cut -d- -f1 || true )
2025-11-22 12:52:47 +01:00
if [ [ -z " $AVAILABLE_PHP_VERSION " ] ] ; then
msg_error " PHP ${ PHP_VERSION } not found in configured repositories "
return 1
fi
fix(php): improve module handling and prevent installation failures (#11358)
Changes to setup_php():
- Add version detection for PHP 8.5+ built-in opcache
- Define BUILTIN_MODULES list for modules included in php-common
(ctype, fileinfo, iconv, tokenizer, phar, posix, etc.)
- Filter out built-in modules before attempting installation
- Verify each package exists via apt-cache before adding to install list
- Skip unavailable packages with informational message instead of error
- Add extended default modules (mysql, sqlite3, pgsql, redis, imagick,
bz2, apcu) to cover ~90% of typical use cases
- Improve error handling with graceful degradation
This prevents installation failures when:
- PHP version has module built into core (e.g., opcache in 8.5+)
- Module is provided by php-common (ctype, fileinfo, etc.)
- Package is renamed or unavailable in specific PHP version
Fixes #11359
2026-01-30 10:29:51 +01:00
# Build module list - verify each package exists before adding
2025-11-22 13:20:18 +01:00
local MODULE_LIST = " php ${ PHP_VERSION } "
fix(php): improve module handling and prevent installation failures (#11358)
Changes to setup_php():
- Add version detection for PHP 8.5+ built-in opcache
- Define BUILTIN_MODULES list for modules included in php-common
(ctype, fileinfo, iconv, tokenizer, phar, posix, etc.)
- Filter out built-in modules before attempting installation
- Verify each package exists via apt-cache before adding to install list
- Skip unavailable packages with informational message instead of error
- Add extended default modules (mysql, sqlite3, pgsql, redis, imagick,
bz2, apcu) to cover ~90% of typical use cases
- Improve error handling with graceful degradation
This prevents installation failures when:
- PHP version has module built into core (e.g., opcache in 8.5+)
- Module is provided by php-common (ctype, fileinfo, etc.)
- Package is renamed or unavailable in specific PHP version
Fixes #11359
2026-01-30 10:29:51 +01:00
local SKIPPED_MODULES = ""
2025-11-22 12:52:47 +01:00
2025-09-11 12:44:13 +02:00
IFS = ',' read -ra MODULES <<< " $COMBINED_MODULES "
for mod in " ${ MODULES [@] } " ; do
fix(php): improve module handling and prevent installation failures (#11358)
Changes to setup_php():
- Add version detection for PHP 8.5+ built-in opcache
- Define BUILTIN_MODULES list for modules included in php-common
(ctype, fileinfo, iconv, tokenizer, phar, posix, etc.)
- Filter out built-in modules before attempting installation
- Verify each package exists via apt-cache before adding to install list
- Skip unavailable packages with informational message instead of error
- Add extended default modules (mysql, sqlite3, pgsql, redis, imagick,
bz2, apcu) to cover ~90% of typical use cases
- Improve error handling with graceful degradation
This prevents installation failures when:
- PHP version has module built into core (e.g., opcache in 8.5+)
- Module is provided by php-common (ctype, fileinfo, etc.)
- Package is renamed or unavailable in specific PHP version
Fixes #11359
2026-01-30 10:29:51 +01:00
mod = $( echo " $mod " | tr -d '[:space:]' )
[ [ -z " $mod " ] ] && continue
local pkg_name = " php ${ PHP_VERSION } - ${ mod } "
# Check if package exists in repository
if apt-cache show " $pkg_name " & >/dev/null; then
MODULE_LIST += " $pkg_name "
else
# Package doesn't exist - could be built-in or renamed
if [ [ -z " $SKIPPED_MODULES " ] ] ; then
SKIPPED_MODULES = " $mod "
else
SKIPPED_MODULES = " ${ SKIPPED_MODULES } , $mod "
fi
fi
2025-09-11 12:44:13 +02:00
done
2025-11-22 12:52:47 +01:00
fix(php): improve module handling and prevent installation failures (#11358)
Changes to setup_php():
- Add version detection for PHP 8.5+ built-in opcache
- Define BUILTIN_MODULES list for modules included in php-common
(ctype, fileinfo, iconv, tokenizer, phar, posix, etc.)
- Filter out built-in modules before attempting installation
- Verify each package exists via apt-cache before adding to install list
- Skip unavailable packages with informational message instead of error
- Add extended default modules (mysql, sqlite3, pgsql, redis, imagick,
bz2, apcu) to cover ~90% of typical use cases
- Improve error handling with graceful degradation
This prevents installation failures when:
- PHP version has module built into core (e.g., opcache in 8.5+)
- Module is provided by php-common (ctype, fileinfo, etc.)
- Package is renamed or unavailable in specific PHP version
Fixes #11359
2026-01-30 10:29:51 +01:00
# Log skipped modules (informational, not an error)
if [ [ -n " $SKIPPED_MODULES " ] ] ; then
msg_info " Skipping unavailable/built-in modules: $SKIPPED_MODULES "
fi
2025-09-11 12:44:13 +02:00
if [ [ " $PHP_FPM " = = "YES" ] ] ; then
fix(php): improve module handling and prevent installation failures (#11358)
Changes to setup_php():
- Add version detection for PHP 8.5+ built-in opcache
- Define BUILTIN_MODULES list for modules included in php-common
(ctype, fileinfo, iconv, tokenizer, phar, posix, etc.)
- Filter out built-in modules before attempting installation
- Verify each package exists via apt-cache before adding to install list
- Skip unavailable packages with informational message instead of error
- Add extended default modules (mysql, sqlite3, pgsql, redis, imagick,
bz2, apcu) to cover ~90% of typical use cases
- Improve error handling with graceful degradation
This prevents installation failures when:
- PHP version has module built into core (e.g., opcache in 8.5+)
- Module is provided by php-common (ctype, fileinfo, etc.)
- Package is renamed or unavailable in specific PHP version
Fixes #11359
2026-01-30 10:29:51 +01:00
if apt-cache show " php ${ PHP_VERSION } -fpm " & >/dev/null; then
MODULE_LIST += " php ${ PHP_VERSION } -fpm "
else
msg_warn " php ${ PHP_VERSION } -fpm not available "
fi
2026-01-28 11:39:48 +01:00
# Create systemd override for PHP-FPM to fix runtime directory issues in LXC containers
mkdir -p /etc/systemd/system/php${ PHP_VERSION } -fpm.service.d/
cat <<EOF >/etc/systemd/system/php${PHP_VE RSION} -fpm.service.d/override.conf
[ Service]
RuntimeDirectory = php
RuntimeDirectoryMode = 0755
EOF
$STD systemctl daemon-reload
2025-06-18 12:07:08 +02:00
fi
2025-09-11 12:44:13 +02:00
# install apache2 with PHP support if requested
if [ [ " $PHP_APACHE " = = "YES" ] ] ; then
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
if ! dpkg -l 2>/dev/null | grep -q " libapache2-mod-php ${ PHP_VERSION } " ; then
2025-11-22 12:52:47 +01:00
msg_info " Installing Apache with PHP ${ PHP_VERSION } module "
install_packages_with_retry "apache2" || {
msg_error "Failed to install Apache"
2025-10-22 06:25:26 -07:00
return 1
}
2025-11-22 13:20:18 +01:00
install_packages_with_retry " libapache2-mod-php ${ PHP_VERSION } " || {
2025-11-22 12:52:47 +01:00
msg_warn " Failed to install libapache2-mod-php ${ PHP_VERSION } , continuing without Apache module "
}
2025-09-11 12:44:13 +02:00
fi
2025-06-18 12:07:08 +02:00
fi
2025-11-22 13:20:18 +01:00
# Install PHP packages (pinning via preferences.d ensures correct version)
2025-11-22 13:23:40 +01:00
msg_info " Installing PHP ${ PHP_VERSION } packages "
fix(php): improve module handling and prevent installation failures (#11358)
Changes to setup_php():
- Add version detection for PHP 8.5+ built-in opcache
- Define BUILTIN_MODULES list for modules included in php-common
(ctype, fileinfo, iconv, tokenizer, phar, posix, etc.)
- Filter out built-in modules before attempting installation
- Verify each package exists via apt-cache before adding to install list
- Skip unavailable packages with informational message instead of error
- Add extended default modules (mysql, sqlite3, pgsql, redis, imagick,
bz2, apcu) to cover ~90% of typical use cases
- Improve error handling with graceful degradation
This prevents installation failures when:
- PHP version has module built into core (e.g., opcache in 8.5+)
- Module is provided by php-common (ctype, fileinfo, etc.)
- Package is renamed or unavailable in specific PHP version
Fixes #11359
2026-01-30 10:29:51 +01:00
# First attempt: Install all verified packages at once
if ! $STD apt install -y $MODULE_LIST 2>/dev/null; then
msg_warn "Bulk installation failed, attempting individual installation"
2025-11-22 13:23:40 +01:00
2025-11-22 13:08:30 +01:00
# Install main package first (critical)
fix(php): improve module handling and prevent installation failures (#11358)
Changes to setup_php():
- Add version detection for PHP 8.5+ built-in opcache
- Define BUILTIN_MODULES list for modules included in php-common
(ctype, fileinfo, iconv, tokenizer, phar, posix, etc.)
- Filter out built-in modules before attempting installation
- Verify each package exists via apt-cache before adding to install list
- Skip unavailable packages with informational message instead of error
- Add extended default modules (mysql, sqlite3, pgsql, redis, imagick,
bz2, apcu) to cover ~90% of typical use cases
- Improve error handling with graceful degradation
This prevents installation failures when:
- PHP version has module built into core (e.g., opcache in 8.5+)
- Module is provided by php-common (ctype, fileinfo, etc.)
- Package is renamed or unavailable in specific PHP version
Fixes #11359
2026-01-30 10:29:51 +01:00
if ! $STD apt install -y " php ${ PHP_VERSION } " 2>/dev/null; then
2025-11-22 12:52:47 +01:00
msg_error " Failed to install php ${ PHP_VERSION } "
return 1
fix(php): improve module handling and prevent installation failures (#11358)
Changes to setup_php():
- Add version detection for PHP 8.5+ built-in opcache
- Define BUILTIN_MODULES list for modules included in php-common
(ctype, fileinfo, iconv, tokenizer, phar, posix, etc.)
- Filter out built-in modules before attempting installation
- Verify each package exists via apt-cache before adding to install list
- Skip unavailable packages with informational message instead of error
- Add extended default modules (mysql, sqlite3, pgsql, redis, imagick,
bz2, apcu) to cover ~90% of typical use cases
- Improve error handling with graceful degradation
This prevents installation failures when:
- PHP version has module built into core (e.g., opcache in 8.5+)
- Module is provided by php-common (ctype, fileinfo, etc.)
- Package is renamed or unavailable in specific PHP version
Fixes #11359
2026-01-30 10:29:51 +01:00
fi
2025-11-22 12:52:47 +01:00
2025-11-22 13:08:30 +01:00
# Try to install Apache module individually if requested
if [ [ " $PHP_APACHE " = = "YES" ] ] ; then
fix(php): improve module handling and prevent installation failures (#11358)
Changes to setup_php():
- Add version detection for PHP 8.5+ built-in opcache
- Define BUILTIN_MODULES list for modules included in php-common
(ctype, fileinfo, iconv, tokenizer, phar, posix, etc.)
- Filter out built-in modules before attempting installation
- Verify each package exists via apt-cache before adding to install list
- Skip unavailable packages with informational message instead of error
- Add extended default modules (mysql, sqlite3, pgsql, redis, imagick,
bz2, apcu) to cover ~90% of typical use cases
- Improve error handling with graceful degradation
This prevents installation failures when:
- PHP version has module built into core (e.g., opcache in 8.5+)
- Module is provided by php-common (ctype, fileinfo, etc.)
- Package is renamed or unavailable in specific PHP version
Fixes #11359
2026-01-30 10:29:51 +01:00
$STD apt install -y " libapache2-mod-php ${ PHP_VERSION } " 2>/dev/null || {
2025-11-22 13:23:40 +01:00
msg_warn " Could not install libapache2-mod-php ${ PHP_VERSION } "
}
2025-11-22 13:08:30 +01:00
fi
fix(php): improve module handling and prevent installation failures (#11358)
Changes to setup_php():
- Add version detection for PHP 8.5+ built-in opcache
- Define BUILTIN_MODULES list for modules included in php-common
(ctype, fileinfo, iconv, tokenizer, phar, posix, etc.)
- Filter out built-in modules before attempting installation
- Verify each package exists via apt-cache before adding to install list
- Skip unavailable packages with informational message instead of error
- Add extended default modules (mysql, sqlite3, pgsql, redis, imagick,
bz2, apcu) to cover ~90% of typical use cases
- Improve error handling with graceful degradation
This prevents installation failures when:
- PHP version has module built into core (e.g., opcache in 8.5+)
- Module is provided by php-common (ctype, fileinfo, etc.)
- Package is renamed or unavailable in specific PHP version
Fixes #11359
2026-01-30 10:29:51 +01:00
# Try to install each package individually
for pkg in $MODULE_LIST ; do
2026-02-22 11:54:21 +01:00
[ [ " $pkg " = = " php ${ PHP_VERSION } " ] ] && continue # Already installed
fix(php): improve module handling and prevent installation failures (#11358)
Changes to setup_php():
- Add version detection for PHP 8.5+ built-in opcache
- Define BUILTIN_MODULES list for modules included in php-common
(ctype, fileinfo, iconv, tokenizer, phar, posix, etc.)
- Filter out built-in modules before attempting installation
- Verify each package exists via apt-cache before adding to install list
- Skip unavailable packages with informational message instead of error
- Add extended default modules (mysql, sqlite3, pgsql, redis, imagick,
bz2, apcu) to cover ~90% of typical use cases
- Improve error handling with graceful degradation
This prevents installation failures when:
- PHP version has module built into core (e.g., opcache in 8.5+)
- Module is provided by php-common (ctype, fileinfo, etc.)
- Package is renamed or unavailable in specific PHP version
Fixes #11359
2026-01-30 10:29:51 +01:00
$STD apt install -y " $pkg " 2>/dev/null || {
msg_warn " Could not install $pkg - continuing without it "
}
2025-11-22 12:52:47 +01:00
done
fi
2025-10-22 06:25:26 -07:00
cache_installed_version "php" " $PHP_VERSION "
2025-04-29 16:04:29 +02:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Patch all relevant php.ini files
2025-09-11 12:44:13 +02:00
local PHP_INI_PATHS = ( " /etc/php/ ${ PHP_VERSION } /cli/php.ini " )
[ [ " $PHP_FPM " = = "YES" ] ] && PHP_INI_PATHS += ( " /etc/php/ ${ PHP_VERSION } /fpm/php.ini " )
[ [ " $PHP_APACHE " = = "YES" ] ] && PHP_INI_PATHS += ( " /etc/php/ ${ PHP_VERSION } /apache2/php.ini " )
for ini in " ${ PHP_INI_PATHS [@] } " ; do
if [ [ -f " $ini " ] ] ; then
2025-10-22 06:25:26 -07:00
$STD sed -i " s|^memory_limit = .*|memory_limit = ${ PHP_MEMORY_LIMIT } | " " $ini "
$STD sed -i " s|^upload_max_filesize = .*|upload_max_filesize = ${ PHP_UPLOAD_MAX_FILESIZE } | " " $ini "
$STD sed -i " s|^post_max_size = .*|post_max_size = ${ PHP_POST_MAX_SIZE } | " " $ini "
$STD sed -i " s|^max_execution_time = .*|max_execution_time = ${ PHP_MAX_EXECUTION_TIME } | " " $ini "
2025-06-18 12:07:08 +02:00
fi
2025-09-11 12:44:13 +02:00
done
2025-06-18 12:07:08 +02:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Patch Apache configuration if needed
2025-09-11 12:44:13 +02:00
if [ [ " $PHP_APACHE " = = "YES" ] ] ; then
for mod in $( ls /etc/apache2/mods-enabled/ 2>/dev/null | grep -E '^php[0-9]\.[0-9]\.conf$' | sed 's/\.conf//' ) ; do
if [ [ " $mod " != " php ${ PHP_VERSION } " ] ] ; then
$STD a2dismod " $mod " || true
2025-06-18 12:07:08 +02:00
fi
2025-09-11 12:44:13 +02:00
done
$STD a2enmod mpm_prefork
$STD a2enmod " php ${ PHP_VERSION } "
2025-10-22 06:25:26 -07:00
safe_service_restart apache2 || true
2025-09-11 12:44:13 +02:00
fi
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Enable and restart PHP-FPM if requested
2025-09-11 12:44:13 +02:00
if [ [ " $PHP_FPM " = = "YES" ] ] ; then
if systemctl list-unit-files | grep -q " php ${ PHP_VERSION } -fpm.service " ; then
$STD systemctl enable php${ PHP_VERSION } -fpm
2025-10-22 06:25:26 -07:00
safe_service_restart php${ PHP_VERSION } -fpm
2025-06-18 12:07:08 +02:00
fi
fi
2025-10-22 06:25:26 -07:00
2025-11-22 12:52:47 +01:00
# Verify PHP installation - critical check
if ! command -v php >/dev/null 2>& 1; then
msg_error "PHP installation verification failed - php command not found"
return 1
fi
local INSTALLED_VERSION = $( php -v 2>/dev/null | awk '/^PHP/{print $2}' | cut -d. -f1,2)
if [ [ " $INSTALLED_VERSION " != " $PHP_VERSION " ] ] ; then
msg_error " PHP version mismatch: requested ${ PHP_VERSION } but got ${ INSTALLED_VERSION } "
msg_error "This indicates a critical package installation issue"
# Don't cache wrong version
return 1
fi
cache_installed_version "php" " $INSTALLED_VERSION "
msg_ok " Setup PHP ${ INSTALLED_VERSION } "
2025-04-29 16:04:29 +02:00
}
2025-04-29 16:20:23 +02:00
2025-05-15 15:18:41 +02:00
# ------------------------------------------------------------------------------
2025-09-11 12:44:13 +02:00
# Installs or upgrades PostgreSQL and optional extensions/modules.
2025-05-15 15:18:41 +02:00
#
# Description:
2025-09-11 12:44:13 +02:00
# - Detects existing PostgreSQL version
# - Dumps all databases before upgrade
# - Adds PGDG repo and installs specified version
# - Installs optional PG_MODULES (e.g. postgis, contrib)
# - Restores dumped data post-upgrade
#
# Variables:
# PG_VERSION - Major PostgreSQL version (e.g. 15, 16) (default: 16)
function setup_postgresql( ) {
local PG_VERSION = " ${ PG_VERSION :- 16 } "
local PG_MODULES = " ${ PG_MODULES :- } "
2025-10-22 06:25:26 -07:00
local DISTRO_ID DISTRO_CODENAME
DISTRO_ID = $( awk -F= '/^ID=/{print $2}' /etc/os-release | tr -d '"' )
DISTRO_CODENAME = $( awk -F= '/^VERSION_CODENAME=/{print $2}' /etc/os-release)
2025-05-15 15:18:41 +02:00
2026-01-12 08:48:36 +01:00
# Ensure non-interactive mode for all apt operations
export DEBIAN_FRONTEND = noninteractive
export NEEDRESTART_MODE = a
export NEEDRESTART_SUSPEND = 1
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Get currently installed version
local CURRENT_PG_VERSION = ""
2025-09-11 12:44:13 +02:00
if command -v psql >/dev/null; then
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
CURRENT_PG_VERSION = " $( psql -V 2>/dev/null | awk '{print $3}' | cut -d. -f1) "
2025-05-05 15:47:43 +02:00
fi
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Scenario 1: Already at correct version
if [ [ " $CURRENT_PG_VERSION " = = " $PG_VERSION " ] ] ; then
msg_info " Update PostgreSQL $PG_VERSION "
ensure_apt_working || return 1
2025-10-22 06:25:26 -07:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Perform upgrade with retry logic (non-fatal if fails)
upgrade_packages_with_retry " postgresql- ${ PG_VERSION } " " postgresql-client- ${ PG_VERSION } " 2>/dev/null || true
cache_installed_version "postgresql" " $PG_VERSION "
msg_ok " Update PostgreSQL $PG_VERSION "
2025-10-22 06:25:26 -07:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Still install modules if specified
if [ [ -n " $PG_MODULES " ] ] ; then
IFS = ',' read -ra MODULES <<< " $PG_MODULES "
for module in " ${ MODULES [@] } " ; do
$STD apt install -y " postgresql- ${ PG_VERSION } - ${ module } " 2>/dev/null || true
done
fi
return 0
fi
2025-10-22 06:25:26 -07:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Scenario 2: Different version - backup, remove old, install new
if [ [ -n " $CURRENT_PG_VERSION " ] ] ; then
msg_info " Upgrade PostgreSQL from $CURRENT_PG_VERSION to $PG_VERSION "
msg_info " Creating backup of PostgreSQL $CURRENT_PG_VERSION databases... "
$STD runuser -u postgres -- pg_dumpall >/var/lib/postgresql/backup_$( date +%F) _v${ CURRENT_PG_VERSION } .sql || {
msg_error "Failed to backup PostgreSQL databases"
return 1
}
$STD systemctl stop postgresql || true
$STD apt purge -y " postgresql- ${ CURRENT_PG_VERSION } " " postgresql-client- ${ CURRENT_PG_VERSION } " 2>/dev/null || true
else
msg_info " Setup PostgreSQL $PG_VERSION "
fi
2025-10-22 06:25:26 -07:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Scenario 3: Fresh install or after removal - setup repo and install
prepare_repository_setup "pgdg" "postgresql" || {
msg_error "Failed to prepare PostgreSQL repository"
return 1
}
2025-10-22 06:25:26 -07:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
local SUITE
case " $DISTRO_CODENAME " in
trixie | forky | sid)
Three-tier defaults system | security improvements | error_handler | improved logging | improved container creation | improved architecture (#9540)
* Refactor Core
Refactored misc/alpine-install.func to improve error handling, network checks, and MOTD setup. Added misc/alpine-tools.func and misc/error_handler.func for modular tool installation and error management. Enhanced misc/api.func with detailed exit code explanations and telemetry functions. Updated misc/core.func for better initialization, validation, and execution helpers. Removed misc/create_lxc.sh as part of cleanup.
* Delete config-file.func
* Update install.func
* Refactor stop_all_services function and variable names
Refactor service stopping logic and improve variable handling
* Refactor installation script and update copyright
Updated copyright information and adjusted package installation commands. Enhanced IPv6 disabling logic and improved container customization process.
* Update install.func
* Update license comment format in install.func
* Refactor IPv6 handling and enhance MOTD and SSH
Refactor IPv6 handling and update OS function. Enhance MOTD with additional details and configure SSH settings.
* big core refactor
* Enhance IPv6 configuration menu options
Updated IPv6 Address Management menu options for clarity and added a new option for fully disabling IPv6.
* Update default Node.js version to 24 LTS
* Update misc/alpine-tools.func
Co-authored-by: Michel Roegl-Brunner <73236783+michelroegl-brunner@users.noreply.github.com>
* indention
* remove debugf and duplicate codes
* Update whiptail backtitles and error codes
Removed '[dev]' from whiptail --backtitle strings for consistency. Refactored custom exit codes in build.func and error_handler.func: updated Proxmox error codes, shifted MySQL/MariaDB codes to 260-263, and removed unused MongoDB code. Updated error descriptions to match new codes.
* comments
* Refactor error handling and clean up debug comments
Standardized bash variable checks, removed unnecessary debug and commented code, and clarified error handling logic in container build and setup scripts. These changes improve code readability and maintainability without altering functional behavior.
* Update build.func
* feat: Improve LXC network checks and LINSTOR storage handling
Enhanced LXC container network setup to check for both IPv4 and IPv6 addresses, added connectivity (ping) tests, and provided troubleshooting tips on failure. Updated storage validation to support LINSTOR, including cluster connectivity checks and special handling for LINSTOR template storage.
---------
Co-authored-by: Michel Roegl-Brunner <73236783+michelroegl-brunner@users.noreply.github.com>
2025-12-04 07:52:18 +01:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
if verify_repo_available "https://apt.postgresql.org/pub/repos/apt" "trixie-pgdg" ; then
SUITE = "trixie-pgdg"
2025-11-17 09:42:02 +01:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
else
Three-tier defaults system | security improvements | error_handler | improved logging | improved container creation | improved architecture (#9540)
* Refactor Core
Refactored misc/alpine-install.func to improve error handling, network checks, and MOTD setup. Added misc/alpine-tools.func and misc/error_handler.func for modular tool installation and error management. Enhanced misc/api.func with detailed exit code explanations and telemetry functions. Updated misc/core.func for better initialization, validation, and execution helpers. Removed misc/create_lxc.sh as part of cleanup.
* Delete config-file.func
* Update install.func
* Refactor stop_all_services function and variable names
Refactor service stopping logic and improve variable handling
* Refactor installation script and update copyright
Updated copyright information and adjusted package installation commands. Enhanced IPv6 disabling logic and improved container customization process.
* Update install.func
* Update license comment format in install.func
* Refactor IPv6 handling and enhance MOTD and SSH
Refactor IPv6 handling and update OS function. Enhance MOTD with additional details and configure SSH settings.
* big core refactor
* Enhance IPv6 configuration menu options
Updated IPv6 Address Management menu options for clarity and added a new option for fully disabling IPv6.
* Update default Node.js version to 24 LTS
* Update misc/alpine-tools.func
Co-authored-by: Michel Roegl-Brunner <73236783+michelroegl-brunner@users.noreply.github.com>
* indention
* remove debugf and duplicate codes
* Update whiptail backtitles and error codes
Removed '[dev]' from whiptail --backtitle strings for consistency. Refactored custom exit codes in build.func and error_handler.func: updated Proxmox error codes, shifted MySQL/MariaDB codes to 260-263, and removed unused MongoDB code. Updated error descriptions to match new codes.
* comments
* Refactor error handling and clean up debug comments
Standardized bash variable checks, removed unnecessary debug and commented code, and clarified error handling logic in container build and setup scripts. These changes improve code readability and maintainability without altering functional behavior.
* Update build.func
* feat: Improve LXC network checks and LINSTOR storage handling
Enhanced LXC container network setup to check for both IPv4 and IPv6 addresses, added connectivity (ping) tests, and provided troubleshooting tips on failure. Updated storage validation to support LINSTOR, including cluster connectivity checks and special handling for LINSTOR template storage.
---------
Co-authored-by: Michel Roegl-Brunner <73236783+michelroegl-brunner@users.noreply.github.com>
2025-12-04 07:52:18 +01:00
SUITE = "bookworm-pgdg"
2025-11-17 09:42:02 +01:00
fi
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
; ;
*)
SUITE = $( get_fallback_suite " $DISTRO_ID " " $DISTRO_CODENAME " "https://apt.postgresql.org/pub/repos/apt" )
SUITE = " ${ SUITE } -pgdg "
; ;
esac
2025-10-22 06:25:26 -07:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
setup_deb822_repo \
"pgdg" \
"https://www.postgresql.org/media/keys/ACCC4CF8.asc" \
"https://apt.postgresql.org/pub/repos/apt" \
" $SUITE " \
2025-11-07 02:49:16 -08:00
"main"
2025-05-15 15:18:41 +02:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
if ! $STD apt update; then
msg_error "APT update failed for PostgreSQL repository"
return 1
fi
2025-05-05 15:47:43 +02:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Install ssl-cert dependency if available
if apt-cache search " ^ssl-cert $" 2>/dev/null | grep -q .; then
$STD apt install -y ssl-cert 2>/dev/null || true
fi
2025-05-05 15:47:43 +02:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Try multiple PostgreSQL package patterns with retry logic
local pg_install_success = false
2025-05-05 15:47:43 +02:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
if apt-cache search " ^postgresql- ${ PG_VERSION } $" 2>/dev/null | grep -q . &&
install_packages_with_retry " postgresql- ${ PG_VERSION } " " postgresql-client- ${ PG_VERSION } " ; then
pg_install_success = true
fi
2025-05-05 15:47:43 +02:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
if [ [ " $pg_install_success " = = false ] ] &&
apt-cache search " ^postgresql-server- ${ PG_VERSION } $" 2>/dev/null | grep -q . &&
$STD apt install -y " postgresql-server- ${ PG_VERSION } " " postgresql-client- ${ PG_VERSION } " 2>/dev/null; then
pg_install_success = true
fi
2025-05-05 15:47:43 +02:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
if [ [ " $pg_install_success " = = false ] ] &&
apt-cache search " ^postgresql $" 2>/dev/null | grep -q . &&
$STD apt install -y postgresql postgresql-client 2>/dev/null; then
pg_install_success = true
fi
2025-05-05 15:47:43 +02:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
if [ [ " $pg_install_success " = = false ] ] ; then
msg_error " PostgreSQL package not available for suite ${ SUITE } "
return 1
fi
2025-05-05 15:47:43 +02:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
if ! command -v psql >/dev/null 2>& 1; then
msg_error "PostgreSQL installed but psql command not found"
return 1
fi
2025-05-05 15:47:43 +02:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Restore database backup if we upgraded from previous version
if [ [ -n " $CURRENT_PG_VERSION " ] ] ; then
msg_info "Restoring PostgreSQL databases from backup..."
$STD runuser -u postgres -- psql </var/lib/postgresql/backup_$( date +%F) _v${ CURRENT_PG_VERSION } .sql 2>/dev/null || {
msg_warn "Failed to restore database backup - this may be expected for major version upgrades"
}
fi
2025-09-11 12:44:13 +02:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
$STD systemctl enable --now postgresql 2>/dev/null || true
# Add PostgreSQL binaries to PATH
if ! grep -q '/usr/lib/postgresql' /etc/environment 2>/dev/null; then
echo 'PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/lib/postgresql/' " ${ PG_VERSION } " '/bin"' >/etc/environment
2025-09-11 12:44:13 +02:00
fi
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
cache_installed_version "postgresql" " $PG_VERSION "
msg_ok " Setup PostgreSQL $PG_VERSION "
# Install optional modules
2025-09-11 12:44:13 +02:00
if [ [ -n " $PG_MODULES " ] ] ; then
IFS = ',' read -ra MODULES <<< " $PG_MODULES "
for module in " ${ MODULES [@] } " ; do
2025-10-22 06:25:26 -07:00
$STD apt install -y " postgresql- ${ PG_VERSION } - ${ module } " 2>/dev/null || true
2025-09-11 12:44:13 +02:00
done
2025-05-05 15:47:43 +02:00
fi
2025-04-29 16:20:23 +02:00
}
2025-05-15 15:18:41 +02:00
2025-11-10 18:51:02 +01:00
# ------------------------------------------------------------------------------
# Creates PostgreSQL database with user and optional extensions
#
# Description:
# - Creates PostgreSQL role with login and password
# - Creates database with UTF8 encoding and template0
# - Installs optional extensions (postgis, pgvector, etc.)
# - Configures ALTER ROLE settings for Django/Rails compatibility
# - Saves credentials to file
# - Exports variables for use in calling script
#
# Usage:
# PG_DB_NAME="myapp_db" PG_DB_USER="myapp_user" setup_postgresql_db
# PG_DB_NAME="immich" PG_DB_USER="immich" PG_DB_EXTENSIONS="pgvector" setup_postgresql_db
# PG_DB_NAME="ghostfolio" PG_DB_USER="ghostfolio" PG_DB_GRANT_SUPERUSER="true" setup_postgresql_db
# PG_DB_NAME="adventurelog" PG_DB_USER="adventurelog" PG_DB_EXTENSIONS="postgis" setup_postgresql_db
#
# Variables:
# PG_DB_NAME - Database name (required)
# PG_DB_USER - Database user (required)
# PG_DB_PASS - Database password (optional, auto-generated if empty)
# PG_DB_EXTENSIONS - Comma-separated list of extensions (optional, e.g. "postgis,pgvector")
# PG_DB_GRANT_SUPERUSER - Grant SUPERUSER privilege (optional, "true" to enable, security risk!)
# PG_DB_SCHEMA_PERMS - Grant schema-level permissions (optional, "true" to enable)
# PG_DB_SKIP_ALTER_ROLE - Skip ALTER ROLE settings (optional, "true" to skip)
# PG_DB_CREDS_FILE - Credentials file path (optional, default: ~/${APPLICATION}.creds)
#
# Exports:
# PG_DB_NAME, PG_DB_USER, PG_DB_PASS - For use in calling script
# ------------------------------------------------------------------------------
function setup_postgresql_db( ) {
# Validation
if [ [ -z " ${ PG_DB_NAME :- } " || -z " ${ PG_DB_USER :- } " ] ] ; then
msg_error "PG_DB_NAME and PG_DB_USER must be set before calling setup_postgresql_db"
return 1
fi
# Generate password if not provided
if [ [ -z " ${ PG_DB_PASS :- } " ] ] ; then
PG_DB_PASS = $( openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13)
fi
msg_info "Setting up PostgreSQL Database"
$STD sudo -u postgres psql -c " CREATE ROLE $PG_DB_USER WITH LOGIN PASSWORD ' $PG_DB_PASS '; "
$STD sudo -u postgres psql -c " CREATE DATABASE $PG_DB_NAME WITH OWNER $PG_DB_USER ENCODING 'UTF8' TEMPLATE template0; "
# Install extensions (comma-separated)
if [ [ -n " ${ PG_DB_EXTENSIONS :- } " ] ] ; then
IFS = ',' read -ra EXT_LIST <<< " ${ PG_DB_EXTENSIONS :- } "
for ext in " ${ EXT_LIST [@] } " ; do
ext = $( echo " $ext " | xargs) # Trim whitespace
$STD sudo -u postgres psql -d " $PG_DB_NAME " -c " CREATE EXTENSION IF NOT EXISTS $ext ; "
done
fi
# ALTER ROLE settings for Django/Rails compatibility (unless skipped)
if [ [ " ${ PG_DB_SKIP_ALTER_ROLE :- } " != "true" ] ] ; then
$STD sudo -u postgres psql -c " ALTER ROLE $PG_DB_USER SET client_encoding TO 'utf8'; "
$STD sudo -u postgres psql -c " ALTER ROLE $PG_DB_USER SET default_transaction_isolation TO 'read committed'; "
$STD sudo -u postgres psql -c " ALTER ROLE $PG_DB_USER SET timezone TO 'UTC'; "
fi
# Schema permissions (if requested)
if [ [ " ${ PG_DB_SCHEMA_PERMS :- } " = = "true" ] ] ; then
$STD sudo -u postgres psql -c " GRANT ALL PRIVILEGES ON DATABASE $PG_DB_NAME TO $PG_DB_USER ; "
$STD sudo -u postgres psql -c " ALTER USER $PG_DB_USER CREATEDB; "
$STD sudo -u postgres psql -d " $PG_DB_NAME " -c " GRANT ALL ON SCHEMA public TO $PG_DB_USER ; "
$STD sudo -u postgres psql -d " $PG_DB_NAME " -c " GRANT CREATE ON SCHEMA public TO $PG_DB_USER ; "
$STD sudo -u postgres psql -d " $PG_DB_NAME " -c " ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON TABLES TO $PG_DB_USER ; "
$STD sudo -u postgres psql -d " $PG_DB_NAME " -c " ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON SEQUENCES TO $PG_DB_USER ; "
fi
# Superuser grant (if requested - WARNING!)
if [ [ " ${ PG_DB_GRANT_SUPERUSER :- } " = = "true" ] ] ; then
msg_warn "Granting SUPERUSER privilege (security risk!)"
$STD sudo -u postgres psql -c " GRANT ALL PRIVILEGES ON DATABASE $PG_DB_NAME to $PG_DB_USER ; "
$STD sudo -u postgres psql -c " ALTER USER $PG_DB_USER WITH SUPERUSER; "
fi
# Save credentials
2025-11-17 16:52:11 +01:00
local app_name = " ${ APPLICATION ,, } "
local CREDS_FILE = " ${ PG_DB_CREDS_FILE :- ${ HOME } / ${ app_name } .creds } "
2025-11-10 18:51:02 +01:00
{
echo "PostgreSQL Credentials"
echo " Database: $PG_DB_NAME "
echo " User: $PG_DB_USER "
echo " Password: $PG_DB_PASS "
} >>" $CREDS_FILE "
msg_ok "Set up PostgreSQL Database"
# Export for use in calling script
export PG_DB_NAME
export PG_DB_USER
export PG_DB_PASS
}
2025-05-15 15:18:41 +02:00
# ------------------------------------------------------------------------------
# Installs rbenv and ruby-build, installs Ruby and optionally Rails.
#
# Description:
# - Downloads rbenv and ruby-build from GitHub
# - Compiles and installs target Ruby version
# - Optionally installs Rails via gem
#
# Variables:
# RUBY_VERSION - Ruby version to install (default: 3.4.4)
# RUBY_INSTALL_RAILS - true/false to install Rails (default: true)
# ------------------------------------------------------------------------------
2025-06-18 12:07:08 +02:00
function setup_ruby( ) {
2025-05-15 15:18:41 +02:00
local RUBY_VERSION = " ${ RUBY_VERSION :- 3 .4.4 } "
local RUBY_INSTALL_RAILS = " ${ RUBY_INSTALL_RAILS :- true } "
local RBENV_DIR = " $HOME /.rbenv "
local RBENV_BIN = " $RBENV_DIR /bin/rbenv "
local PROFILE_FILE = " $HOME /.profile "
2025-10-22 06:25:26 -07:00
local TMP_DIR = $( mktemp -d)
2025-05-15 15:18:41 +02:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Get currently installed Ruby version
local CURRENT_RUBY_VERSION = ""
if [ [ -x " $RBENV_BIN " ] ] ; then
CURRENT_RUBY_VERSION = $( " $RBENV_BIN " global 2>/dev/null || echo "" )
fi
# Scenario 1: Already at correct Ruby version
if [ [ " $CURRENT_RUBY_VERSION " = = " $RUBY_VERSION " ] ] ; then
msg_info " Update Ruby $RUBY_VERSION "
cache_installed_version "ruby" " $RUBY_VERSION "
msg_ok " Update Ruby $RUBY_VERSION "
return 0
fi
# Scenario 2: Different version - reinstall
if [ [ -n " $CURRENT_RUBY_VERSION " ] ] ; then
msg_info " Upgrade Ruby from $CURRENT_RUBY_VERSION to $RUBY_VERSION "
else
msg_info " Setup Ruby $RUBY_VERSION "
fi
2025-05-15 15:18:41 +02:00
2025-10-22 06:25:26 -07:00
ensure_apt_working || return 1
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Install build dependencies with fallbacks
2025-10-22 06:25:26 -07:00
local ruby_deps = ( )
local dep_variations = (
"jq"
"autoconf"
"patch"
"build-essential"
"libssl-dev"
"libyaml-dev"
"libreadline-dev|libreadline6-dev"
"zlib1g-dev"
"libgmp-dev"
"libncurses-dev|libncurses5-dev"
"libffi-dev"
"libgdbm-dev"
"libdb-dev"
"uuid-dev"
)
for dep_pattern in " ${ dep_variations [@] } " ; do
if [ [ " $dep_pattern " = = *"|" * ] ] ; then
IFS = '|' read -ra variations <<< " $dep_pattern "
for var in " ${ variations [@] } " ; do
if apt-cache search " ^ ${ var } $" 2>/dev/null | grep -q .; then
ruby_deps += ( " $var " )
break
fi
done
else
if apt-cache search " ^ ${ dep_pattern } $" 2>/dev/null | grep -q .; then
ruby_deps += ( " $dep_pattern " )
fi
fi
done
if [ [ ${# ruby_deps [@] } -gt 0 ] ] ; then
$STD apt install -y " ${ ruby_deps [@] } " 2>/dev/null || true
else
msg_error "No Ruby build dependencies available"
2025-05-15 15:18:41 +02:00
rm -rf " $TMP_DIR "
return 1
fi
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Download and build rbenv if needed
if [ [ ! -x " $RBENV_BIN " ] ] ; then
local RBENV_RELEASE
local rbenv_json
rbenv_json = $( curl -fsSL --max-time 15 https://api.github.com/repos/rbenv/rbenv/releases/latest 2>/dev/null || echo "" )
2025-10-22 06:25:26 -07:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
if [ [ -z " $rbenv_json " ] ] ; then
msg_error "Failed to fetch latest rbenv version from GitHub"
rm -rf " $TMP_DIR "
return 1
fi
2025-10-22 06:25:26 -07:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
RBENV_RELEASE = $( echo " $rbenv_json " | jq -r '.tag_name' 2>/dev/null | sed 's/^v//' || echo "" )
2025-05-15 15:18:41 +02:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
if [ [ -z " $RBENV_RELEASE " ] ] ; then
msg_error "Could not parse rbenv version from GitHub response"
rm -rf " $TMP_DIR "
return 1
fi
curl -fsSL " https://github.com/rbenv/rbenv/archive/refs/tags/v ${ RBENV_RELEASE } .tar.gz " -o " $TMP_DIR /rbenv.tar.gz " || {
msg_error "Failed to download rbenv"
rm -rf " $TMP_DIR "
return 1
}
tar -xzf " $TMP_DIR /rbenv.tar.gz " -C " $TMP_DIR " || {
msg_error "Failed to extract rbenv"
rm -rf " $TMP_DIR "
return 1
}
mkdir -p " $RBENV_DIR "
cp -r " $TMP_DIR /rbenv- ${ RBENV_RELEASE } /. " " $RBENV_DIR / "
( cd " $RBENV_DIR " && src/configure && $STD make -C src) || {
msg_error "Failed to build rbenv"
rm -rf " $TMP_DIR "
return 1
}
# Setup profile
if ! grep -q 'rbenv init' " $PROFILE_FILE " 2>/dev/null; then
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >>" $PROFILE_FILE "
echo 'eval "$(rbenv init -)"' >>" $PROFILE_FILE "
fi
2025-05-15 15:18:41 +02:00
fi
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Install ruby-build plugin
if [ [ ! -d " $RBENV_DIR /plugins/ruby-build " ] ] ; then
local RUBY_BUILD_RELEASE
local ruby_build_json
ruby_build_json = $( curl -fsSL --max-time 15 https://api.github.com/repos/rbenv/ruby-build/releases/latest 2>/dev/null || echo "" )
2025-10-22 06:25:26 -07:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
if [ [ -z " $ruby_build_json " ] ] ; then
msg_error "Failed to fetch latest ruby-build version from GitHub"
rm -rf " $TMP_DIR "
return 1
fi
2025-10-22 06:25:26 -07:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
RUBY_BUILD_RELEASE = $( echo " $ruby_build_json " | jq -r '.tag_name' 2>/dev/null | sed 's/^v//' || echo "" )
2025-05-15 15:18:41 +02:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
if [ [ -z " $RUBY_BUILD_RELEASE " ] ] ; then
msg_error "Could not parse ruby-build version from GitHub response"
rm -rf " $TMP_DIR "
return 1
fi
curl -fsSL " https://github.com/rbenv/ruby-build/archive/refs/tags/v ${ RUBY_BUILD_RELEASE } .tar.gz " -o " $TMP_DIR /ruby-build.tar.gz " || {
msg_error "Failed to download ruby-build"
rm -rf " $TMP_DIR "
return 1
}
tar -xzf " $TMP_DIR /ruby-build.tar.gz " -C " $TMP_DIR " || {
msg_error "Failed to extract ruby-build"
rm -rf " $TMP_DIR "
return 1
}
mkdir -p " $RBENV_DIR /plugins/ruby-build "
cp -r " $TMP_DIR /ruby-build- ${ RUBY_BUILD_RELEASE } /. " " $RBENV_DIR /plugins/ruby-build/ "
2025-05-15 15:18:41 +02:00
fi
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Setup PATH and install Ruby version
2025-05-15 15:18:41 +02:00
export PATH = " $RBENV_DIR /bin: $PATH "
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
eval " $( " $RBENV_BIN " init - bash) " 2>/dev/null || true
2025-05-15 15:18:41 +02:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
if ! " $RBENV_BIN " versions --bare 2>/dev/null | grep -qx " $RUBY_VERSION " ; then
2025-10-22 06:25:26 -07:00
$STD " $RBENV_BIN " install " $RUBY_VERSION " || {
msg_error " Failed to install Ruby $RUBY_VERSION "
rm -rf " $TMP_DIR "
return 1
}
2025-05-15 15:18:41 +02:00
fi
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
" $RBENV_BIN " global " $RUBY_VERSION " || {
msg_error " Failed to set Ruby $RUBY_VERSION as global version "
rm -rf " $TMP_DIR "
return 1
}
2025-05-15 15:18:41 +02:00
hash -r
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Install Rails if requested
2025-05-15 15:18:41 +02:00
if [ [ " $RUBY_INSTALL_RAILS " = = "true" ] ] ; then
2025-10-22 06:25:26 -07:00
$STD gem install rails || {
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
msg_warn "Failed to install Rails - Ruby installation successful"
2025-10-22 06:25:26 -07:00
}
2025-05-15 15:18:41 +02:00
fi
2025-09-11 12:44:13 +02:00
rm -rf " $TMP_DIR "
2025-10-22 06:25:26 -07:00
cache_installed_version "ruby" " $RUBY_VERSION "
2025-09-11 12:44:13 +02:00
msg_ok " Setup Ruby $RUBY_VERSION "
2025-05-18 09:27:55 +02:00
}
2025-05-27 14:29:50 +02:00
2025-10-22 06:25:26 -07:00
# ------------------------------------------------------------------------------
2026-01-28 11:08:52 +01:00
# Installs or updates MeiliSearch search engine.
#
# Description:
# - Fresh install: Downloads binary, creates config/service, starts
# - Update: Checks for new release, updates binary if available
# - Waits for service to be ready before returning
# - Exports API keys for use by caller
#
# Variables:
# MEILISEARCH_BIND - Bind address (default: 127.0.0.1:7700)
# MEILISEARCH_ENV - Environment: production/development (default: production)
# MEILISEARCH_DB_PATH - Database path (default: /var/lib/meilisearch/data)
#
# Exports:
# MEILISEARCH_MASTER_KEY - The master key for admin access
# MEILISEARCH_API_KEY - The default search API key
# MEILISEARCH_API_KEY_UID - The UID of the default API key
#
# Example (install script):
# setup_meilisearch
#
# Example (CT update_script):
# setup_meilisearch
# ------------------------------------------------------------------------------
function setup_meilisearch( ) {
local MEILISEARCH_BIND = " ${ MEILISEARCH_BIND :- 127 .0.0.1 : 7700 } "
local MEILISEARCH_ENV = " ${ MEILISEARCH_ENV :- production } "
local MEILISEARCH_DB_PATH = " ${ MEILISEARCH_DB_PATH :- /var/lib/meilisearch/data } "
local MEILISEARCH_DUMP_DIR = " ${ MEILISEARCH_DUMP_DIR :- /var/lib/meilisearch/dumps } "
local MEILISEARCH_SNAPSHOT_DIR = " ${ MEILISEARCH_SNAPSHOT_DIR :- /var/lib/meilisearch/snapshots } "
# Get bind address for health checks
local MEILISEARCH_HOST = " ${ MEILISEARCH_BIND %% : * } "
local MEILISEARCH_PORT = " ${ MEILISEARCH_BIND ##* : } "
[ [ " $MEILISEARCH_HOST " = = "0.0.0.0" ] ] && MEILISEARCH_HOST = "127.0.0.1"
# Update mode: MeiliSearch already installed
if [ [ -f /usr/bin/meilisearch ] ] ; then
if check_for_gh_release "meilisearch" "meilisearch/meilisearch" ; then
msg_info "Updating MeiliSearch"
2026-01-30 10:20:57 +01:00
# Get current and new version for compatibility check
local CURRENT_VERSION NEW_VERSION
CURRENT_VERSION = $( /usr/bin/meilisearch --version 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1) || CURRENT_VERSION = "0.0.0"
NEW_VERSION = " ${ CHECK_UPDATE_RELEASE #v } "
# Extract major.minor for comparison (Meilisearch requires dump/restore between minor versions)
local CURRENT_MAJOR_MINOR NEW_MAJOR_MINOR
CURRENT_MAJOR_MINOR = $( echo " $CURRENT_VERSION " | cut -d. -f1,2)
NEW_MAJOR_MINOR = $( echo " $NEW_VERSION " | cut -d. -f1,2)
# Determine if migration is needed (different major.minor = incompatible DB format)
local NEEDS_MIGRATION = false
if [ [ " $CURRENT_MAJOR_MINOR " != " $NEW_MAJOR_MINOR " ] ] ; then
NEEDS_MIGRATION = true
msg_info " MeiliSearch version change detected ( ${ CURRENT_VERSION } → ${ NEW_VERSION } ), preparing data migration "
fi
# Read config values for dump/restore
local MEILI_HOST MEILI_PORT MEILI_MASTER_KEY MEILI_DUMP_DIR
MEILI_HOST = " ${ MEILISEARCH_HOST :- 127 .0.0.1 } "
MEILI_PORT = " ${ MEILISEARCH_PORT :- 7700 } "
MEILI_DUMP_DIR = " ${ MEILISEARCH_DUMP_DIR :- /var/lib/meilisearch/dumps } "
MEILI_MASTER_KEY = $( grep -E "^master_key\s*=" /etc/meilisearch.toml 2>/dev/null | sed 's/.*=\s*"\(.*\)"/\1/' | tr -d ' ' )
# Create dump before update if migration is needed
local DUMP_UID = ""
if [ [ " $NEEDS_MIGRATION " = = "true" ] ] && [ [ -n " $MEILI_MASTER_KEY " ] ] ; then
msg_info "Creating MeiliSearch data dump before upgrade"
# Trigger dump creation
local DUMP_RESPONSE
DUMP_RESPONSE = $( curl -s -X POST " http:// ${ MEILI_HOST } : ${ MEILI_PORT } /dumps " \
-H " Authorization: Bearer ${ MEILI_MASTER_KEY } " \
-H "Content-Type: application/json" 2>/dev/null) || true
2026-01-30 10:29:08 +01:00
# The initial response only contains taskUid, not dumpUid
# dumpUid is only available after the task completes
local TASK_UID
TASK_UID = $( echo " $DUMP_RESPONSE " | grep -oP '"taskUid":\s*\K[0-9]+' || true )
if [ [ -n " $TASK_UID " ] ] ; then
msg_info " Waiting for dump task ${ TASK_UID } to complete... "
local MAX_WAIT = 120
local WAITED = 0
local TASK_RESULT = ""
2026-02-22 11:54:21 +01:00
2026-01-30 10:29:08 +01:00
while [ [ $WAITED -lt $MAX_WAIT ] ] ; do
TASK_RESULT = $( curl -s " http:// ${ MEILI_HOST } : ${ MEILI_PORT } /tasks/ ${ TASK_UID } " \
-H " Authorization: Bearer ${ MEILI_MASTER_KEY } " 2>/dev/null) || true
2026-02-22 11:54:21 +01:00
2026-01-30 10:29:08 +01:00
local TASK_STATUS
TASK_STATUS = $( echo " $TASK_RESULT " | grep -oP '"status":\s*"\K[^"]+' || true )
2026-02-22 11:54:21 +01:00
2026-01-30 10:29:08 +01:00
if [ [ " $TASK_STATUS " = = "succeeded" ] ] ; then
# Extract dumpUid from the completed task details
DUMP_UID = $( echo " $TASK_RESULT " | grep -oP '"dumpUid":\s*"\K[^"]+' || true )
if [ [ -n " $DUMP_UID " ] ] ; then
2026-01-30 10:20:57 +01:00
msg_ok " MeiliSearch dump created successfully: ${ DUMP_UID } "
2026-01-30 10:29:08 +01:00
else
msg_warn "Dump task succeeded but could not extract dumpUid"
2026-01-30 10:20:57 +01:00
fi
2026-01-30 10:29:08 +01:00
break
elif [ [ " $TASK_STATUS " = = "failed" ] ] ; then
local ERROR_MSG
ERROR_MSG = $( echo " $TASK_RESULT " | grep -oP '"message":\s*"\K[^"]+' || echo "Unknown error" )
msg_warn " MeiliSearch dump failed: ${ ERROR_MSG } "
break
2026-01-30 10:20:57 +01:00
fi
2026-01-30 10:29:08 +01:00
sleep 2
WAITED = $(( WAITED + 2 ))
done
if [ [ $WAITED -ge $MAX_WAIT ] ] ; then
msg_warn " MeiliSearch dump timed out after ${ MAX_WAIT } s "
2026-01-30 10:20:57 +01:00
fi
else
2026-01-30 10:29:08 +01:00
msg_warn "Could not trigger MeiliSearch dump (no taskUid in response)"
msg_info " Response was: ${ DUMP_RESPONSE :- empty } "
fi
fi
# If migration is needed but dump failed, we have options:
# 1. Abort the update (safest, but annoying)
# 2. Backup data directory and proceed (allows manual recovery)
# 3. Just proceed and hope for the best (dangerous)
# We choose option 2: backup and proceed with warning
if [ [ " $NEEDS_MIGRATION " = = "true" ] ] && [ [ -z " $DUMP_UID " ] ] ; then
local MEILI_DB_PATH
MEILI_DB_PATH = $( grep -E "^db_path\s*=" /etc/meilisearch.toml 2>/dev/null | sed 's/.*=\s*"\(.*\)"/\1/' | tr -d ' ' )
MEILI_DB_PATH = " ${ MEILI_DB_PATH :- /var/lib/meilisearch/data } "
2026-02-22 11:54:21 +01:00
2026-01-30 10:29:08 +01:00
if [ [ -d " $MEILI_DB_PATH " ] ] && [ [ -n " $( ls -A " $MEILI_DB_PATH " 2>/dev/null) " ] ] ; then
local BACKUP_PATH = " ${ MEILI_DB_PATH } .backup. $( date +%Y%m%d%H%M%S) "
msg_warn " Backing up MeiliSearch data to ${ BACKUP_PATH } "
mv " $MEILI_DB_PATH " " $BACKUP_PATH "
mkdir -p " $MEILI_DB_PATH "
msg_info "Data backed up. After update, you may need to reindex your data."
msg_info " Old data is preserved at: ${ BACKUP_PATH } "
2026-01-30 10:20:57 +01:00
fi
fi
# Stop service and update binary
2026-01-28 11:08:52 +01:00
systemctl stop meilisearch
fetch_and_deploy_gh_release "meilisearch" "meilisearch/meilisearch" "binary"
2026-01-30 10:20:57 +01:00
# If migration needed and dump was created, remove old data and import dump
if [ [ " $NEEDS_MIGRATION " = = "true" ] ] && [ [ -n " $DUMP_UID " ] ] ; then
local MEILI_DB_PATH
MEILI_DB_PATH = $( grep -E "^db_path\s*=" /etc/meilisearch.toml 2>/dev/null | sed 's/.*=\s*"\(.*\)"/\1/' | tr -d ' ' )
MEILI_DB_PATH = " ${ MEILI_DB_PATH :- /var/lib/meilisearch/data } "
msg_info "Removing old MeiliSearch database for migration"
rm -rf " ${ MEILI_DB_PATH : ? } " /*
2026-01-30 10:29:08 +01:00
# Import dump using CLI flag (this is the supported method)
local DUMP_FILE = " ${ MEILI_DUMP_DIR } / ${ DUMP_UID } .dump "
if [ [ -f " $DUMP_FILE " ] ] ; then
msg_info " Importing dump: ${ DUMP_FILE } "
2026-02-22 11:54:21 +01:00
2026-01-30 10:29:08 +01:00
# Start meilisearch with --import-dump flag
# This is a one-time import that happens during startup
/usr/bin/meilisearch --config-file-path /etc/meilisearch.toml --import-dump " $DUMP_FILE " &
local MEILI_PID = $!
2026-02-22 11:54:21 +01:00
2026-01-30 10:29:08 +01:00
# Wait for meilisearch to become healthy (import happens during startup)
msg_info "Waiting for MeiliSearch to import and start..."
2026-01-30 10:20:57 +01:00
local MAX_WAIT = 300
local WAITED = 0
while [ [ $WAITED -lt $MAX_WAIT ] ] ; do
2026-01-30 10:29:08 +01:00
if curl -sf " http:// ${ MEILI_HOST } : ${ MEILI_PORT } /health " & >/dev/null; then
msg_ok "MeiliSearch is healthy after import"
2026-01-30 10:20:57 +01:00
break
2026-01-30 10:29:08 +01:00
fi
# Check if process is still running
if ! kill -0 $MEILI_PID 2>/dev/null; then
msg_warn "MeiliSearch process exited during import"
2026-01-30 10:20:57 +01:00
break
fi
sleep 3
WAITED = $(( WAITED + 3 ))
done
2026-02-22 11:54:21 +01:00
2026-01-30 10:29:08 +01:00
# Stop the manual process
2026-01-30 10:20:57 +01:00
kill $MEILI_PID 2>/dev/null || true
2026-01-30 10:29:08 +01:00
sleep 2
2026-02-22 11:54:21 +01:00
2026-01-30 10:29:08 +01:00
# Start via systemd for proper management
systemctl start meilisearch
2026-02-22 11:54:21 +01:00
2026-01-30 10:29:08 +01:00
if systemctl is-active --quiet meilisearch; then
msg_ok "MeiliSearch migrated successfully"
else
msg_warn "MeiliSearch failed to start after migration - check logs with: journalctl -u meilisearch"
fi
else
msg_warn " Dump file not found: ${ DUMP_FILE } "
2026-01-30 10:20:57 +01:00
systemctl start meilisearch
fi
else
systemctl start meilisearch
fi
2026-01-28 11:08:52 +01:00
msg_ok "Updated MeiliSearch"
fi
return 0
fi
# Fresh install
msg_info "Setup MeiliSearch"
# Install binary
fetch_and_deploy_gh_release "meilisearch" "meilisearch/meilisearch" "binary" || {
msg_error "Failed to install MeiliSearch binary"
return 1
}
# Download default config
curl -fsSL https://raw.githubusercontent.com/meilisearch/meilisearch/latest/config.toml -o /etc/meilisearch.toml || {
msg_error "Failed to download MeiliSearch config"
return 1
}
# Generate master key
MEILISEARCH_MASTER_KEY = $( openssl rand -base64 12)
export MEILISEARCH_MASTER_KEY
# Configure
sed -i \
-e " s|^env =.*|env = \" ${ MEILISEARCH_ENV } \"| " \
-e " s|^# master_key =.*|master_key = \" ${ MEILISEARCH_MASTER_KEY } \"| " \
-e " s|^db_path =.*|db_path = \" ${ MEILISEARCH_DB_PATH } \"| " \
-e " s|^dump_dir =.*|dump_dir = \" ${ MEILISEARCH_DUMP_DIR } \"| " \
-e " s|^snapshot_dir =.*|snapshot_dir = \" ${ MEILISEARCH_SNAPSHOT_DIR } \"| " \
-e 's|^# no_analytics = true|no_analytics = true|' \
-e " s|^http_addr =.*|http_addr = \" ${ MEILISEARCH_BIND } \"| " \
/etc/meilisearch.toml
# Create data directories
mkdir -p " ${ MEILISEARCH_DB_PATH } " " ${ MEILISEARCH_DUMP_DIR } " " ${ MEILISEARCH_SNAPSHOT_DIR } "
# Create systemd service
cat <<EOF >/etc/systemd/system/meilisearch.service
[ Unit]
Description = Meilisearch
After = network.target
[ Service]
ExecStart = /usr/bin/meilisearch --config-file-path /etc/meilisearch.toml
Restart = always
[ Install]
WantedBy = multi-user.target
EOF
# Enable and start service
systemctl daemon-reload
systemctl enable -q --now meilisearch
# Wait for MeiliSearch to be ready (up to 30 seconds)
for i in { 1..30} ; do
if curl -s -o /dev/null -w "%{http_code}" " http:// ${ MEILISEARCH_HOST } : ${ MEILISEARCH_PORT } /health " 2>/dev/null | grep -q "200" ; then
break
fi
sleep 1
done
# Verify service is running
if ! systemctl is-active --quiet meilisearch; then
msg_error "MeiliSearch service failed to start"
return 1
fi
# Get API keys with retry logic
MEILISEARCH_API_KEY = ""
for i in { 1..10} ; do
MEILISEARCH_API_KEY = $( curl -s -X GET " http:// ${ MEILISEARCH_HOST } : ${ MEILISEARCH_PORT } /keys " \
2026-02-22 11:54:21 +01:00
-H " Authorization: Bearer ${ MEILISEARCH_MASTER_KEY } " 2>/dev/null |
2026-01-28 11:08:52 +01:00
grep -o '"key":"[^"]*"' | head -n 1 | sed 's/"key":"//;s/"//' ) || true
[ [ -n " $MEILISEARCH_API_KEY " ] ] && break
sleep 2
done
MEILISEARCH_API_KEY_UID = $( curl -s -X GET " http:// ${ MEILISEARCH_HOST } : ${ MEILISEARCH_PORT } /keys " \
2026-02-22 11:54:21 +01:00
-H " Authorization: Bearer ${ MEILISEARCH_MASTER_KEY } " 2>/dev/null |
2026-01-28 11:08:52 +01:00
grep -o '"uid":"[^"]*"' | head -n 1 | sed 's/"uid":"//;s/"//' ) || true
export MEILISEARCH_API_KEY
export MEILISEARCH_API_KEY_UID
# Cache version
local MEILISEARCH_VERSION
MEILISEARCH_VERSION = $( /usr/bin/meilisearch --version 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1) || true
cache_installed_version "meilisearch" " ${ MEILISEARCH_VERSION :- unknown } "
msg_ok " Setup MeiliSearch ${ MEILISEARCH_VERSION :- } "
}
# ------------------------------------------------------------------------------
2025-10-22 06:25:26 -07:00
# Installs or upgrades ClickHouse database server.
#
# Description:
# - Adds ClickHouse official repository
# - Installs specified version
# - Configures systemd service
# - Supports Debian/Ubuntu with fallback mechanism
#
# Variables:
# CLICKHOUSE_VERSION - ClickHouse version to install (default: latest)
# ------------------------------------------------------------------------------
function setup_clickhouse( ) {
local CLICKHOUSE_VERSION = " ${ CLICKHOUSE_VERSION :- latest } "
local DISTRO_ID DISTRO_CODENAME
DISTRO_ID = $( awk -F= '/^ID=/{print $2}' /etc/os-release | tr -d '"' )
DISTRO_CODENAME = $( awk -F= '/^VERSION_CODENAME=/{print $2}' /etc/os-release)
2026-01-12 08:48:36 +01:00
# Ensure non-interactive mode for all apt operations
export DEBIAN_FRONTEND = noninteractive
export NEEDRESTART_MODE = a
export NEEDRESTART_SUSPEND = 1
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Resolve "latest" version
2025-10-22 06:25:26 -07:00
if [ [ " $CLICKHOUSE_VERSION " = = "latest" ] ] ; then
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
CLICKHOUSE_VERSION = $( curl -fsSL --max-time 15 https://packages.clickhouse.com/tgz/stable/ 2>/dev/null |
2025-10-22 06:25:26 -07:00
grep -oP 'clickhouse-common-static-\K[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' |
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
sort -V | tail -n1 || echo "" )
2025-10-22 06:25:26 -07:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Fallback to GitHub API if package server failed
2025-10-22 06:25:26 -07:00
if [ [ -z " $CLICKHOUSE_VERSION " ] ] ; then
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
CLICKHOUSE_VERSION = $( curl -fsSL --max-time 15 https://api.github.com/repos/ClickHouse/ClickHouse/releases/latest 2>/dev/null |
grep -oP '"tag_name":\s*"v\K[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' | head -n1 || echo "" )
2025-10-22 06:25:26 -07:00
fi
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
[ [ -z " $CLICKHOUSE_VERSION " ] ] && {
msg_error "Could not determine latest ClickHouse version from any source"
2025-10-22 06:25:26 -07:00
return 1
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
}
2025-10-22 06:25:26 -07:00
fi
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Get currently installed version
2025-10-22 06:25:26 -07:00
local CURRENT_VERSION = ""
if command -v clickhouse-server >/dev/null 2>& 1; then
CURRENT_VERSION = $( clickhouse-server --version 2>/dev/null | grep -oP 'version \K[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' | head -n1)
fi
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Scenario 1: Already at target version - just update packages
if [ [ -n " $CURRENT_VERSION " && " $CURRENT_VERSION " = = " $CLICKHOUSE_VERSION " ] ] ; then
msg_info " Update ClickHouse $CLICKHOUSE_VERSION "
ensure_apt_working || return 1
2025-10-22 06:25:26 -07:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Perform upgrade with retry logic (non-fatal if fails)
upgrade_packages_with_retry "clickhouse-server" "clickhouse-client" || true
cache_installed_version "clickhouse" " $CLICKHOUSE_VERSION "
msg_ok " Update ClickHouse $CLICKHOUSE_VERSION "
2025-10-22 06:25:26 -07:00
return 0
fi
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Scenario 2: Different version - clean upgrade
if [ [ -n " $CURRENT_VERSION " && " $CURRENT_VERSION " != " $CLICKHOUSE_VERSION " ] ] ; then
msg_info " Upgrade ClickHouse from $CURRENT_VERSION to $CLICKHOUSE_VERSION "
stop_all_services "clickhouse-server"
remove_old_tool_version "clickhouse"
else
msg_info " Setup ClickHouse $CLICKHOUSE_VERSION "
2025-10-22 06:25:26 -07:00
fi
ensure_dependencies apt-transport-https ca-certificates dirmngr gnupg
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Prepare repository (cleanup + validation)
prepare_repository_setup "clickhouse" || {
msg_error "Failed to prepare ClickHouse repository"
return 1
}
2025-10-22 06:25:26 -07:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Setup repository (ClickHouse uses 'stable' suite)
2025-10-22 06:25:26 -07:00
setup_deb822_repo \
"clickhouse" \
"https://packages.clickhouse.com/rpm/lts/repodata/repomd.xml.key" \
"https://packages.clickhouse.com/deb" \
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
"stable" \
2025-11-07 02:49:16 -08:00
"main"
2025-10-22 06:25:26 -07:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Install packages with retry logic
$STD apt update || {
2025-10-22 06:25:26 -07:00
msg_error "APT update failed for ClickHouse repository"
return 1
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
}
2025-10-22 06:25:26 -07:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
install_packages_with_retry "clickhouse-server" "clickhouse-client" || {
2025-10-22 06:25:26 -07:00
msg_error "Failed to install ClickHouse packages"
return 1
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
}
2025-10-22 06:25:26 -07:00
# Verify installation
if ! command -v clickhouse-server >/dev/null 2>& 1; then
msg_error "ClickHouse installation completed but clickhouse-server command not found"
return 1
fi
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Setup data directory
2025-10-22 06:25:26 -07:00
mkdir -p /var/lib/clickhouse
if id clickhouse >/dev/null 2>& 1; then
chown -R clickhouse:clickhouse /var/lib/clickhouse
fi
# Enable and start service
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
$STD systemctl enable clickhouse-server || {
msg_warn "Failed to enable clickhouse-server service"
}
2025-10-22 06:25:26 -07:00
safe_service_restart clickhouse-server || true
cache_installed_version "clickhouse" " $CLICKHOUSE_VERSION "
msg_ok " Setup ClickHouse $CLICKHOUSE_VERSION "
}
2025-05-27 14:29:50 +02:00
# ------------------------------------------------------------------------------
# Installs Rust toolchain and optional global crates via cargo.
#
# Description:
# - Installs rustup (if missing)
# - Installs or updates desired Rust toolchain (stable, nightly, or versioned)
# - Installs or updates specified global crates using `cargo install`
#
# Notes:
# - Skips crate install if exact version is already present
# - Updates crate if newer version or different version is requested
#
# Variables:
# RUST_TOOLCHAIN - Rust toolchain to install (default: stable)
# RUST_CRATES - Comma-separated list of crates (e.g. "cargo-edit,wasm-pack@0.12.1")
# ------------------------------------------------------------------------------
2025-06-18 12:07:08 +02:00
function setup_rust( ) {
2025-05-27 14:29:50 +02:00
local RUST_TOOLCHAIN = " ${ RUST_TOOLCHAIN :- stable } "
local RUST_CRATES = " ${ RUST_CRATES :- } "
local CARGO_BIN = " ${ HOME } /.cargo/bin "
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Get currently installed version
local CURRENT_VERSION = ""
if command -v rustc & >/dev/null; then
2025-12-15 15:22:32 +01:00
CURRENT_VERSION = $( rustc --version 2>/dev/null | awk '{print $2}' 2>/dev/null) || true
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
fi
# Scenario 1: Rustup not installed - fresh install
2025-05-27 14:29:50 +02:00
if ! command -v rustup & >/dev/null; then
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
msg_info " Setup Rust ( $RUST_TOOLCHAIN ) "
2025-10-22 06:25:26 -07:00
curl -fsSL https://sh.rustup.rs | $STD sh -s -- -y --default-toolchain " $RUST_TOOLCHAIN " || {
msg_error "Failed to install Rust"
return 1
}
2025-05-27 14:29:50 +02:00
export PATH = " $CARGO_BIN : $PATH "
echo 'export PATH="$HOME/.cargo/bin:$PATH"' >>" $HOME /.profile "
2025-11-13 12:38:04 +01:00
# Verify installation
if ! command -v rustc >/dev/null 2>& 1; then
msg_error "Rust binary not found after installation"
return 1
fi
2025-12-15 15:22:32 +01:00
local RUST_VERSION
RUST_VERSION = $( rustc --version 2>/dev/null | awk '{print $2}' 2>/dev/null) || true
2025-11-13 12:38:04 +01:00
if [ [ -z " $RUST_VERSION " ] ] ; then
msg_error "Failed to determine Rust version"
return 1
fi
2025-10-22 06:25:26 -07:00
cache_installed_version "rust" " $RUST_VERSION "
msg_ok " Setup Rust $RUST_VERSION "
2025-05-27 14:29:50 +02:00
else
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Scenario 2: Rustup already installed - update/maintain
msg_info " Update Rust ( $RUST_TOOLCHAIN ) "
2025-11-13 12:38:04 +01:00
# Ensure default toolchain is set
$STD rustup default " $RUST_TOOLCHAIN " 2>/dev/null || {
# If default fails, install the toolchain first
$STD rustup install " $RUST_TOOLCHAIN " || {
msg_error " Failed to install Rust toolchain $RUST_TOOLCHAIN "
return 1
}
$STD rustup default " $RUST_TOOLCHAIN " || {
msg_error "Failed to set default Rust toolchain"
return 1
}
2025-10-22 06:25:26 -07:00
}
2025-11-13 12:38:04 +01:00
# Update to latest patch version
2025-11-21 15:22:01 +01:00
$STD rustup update " $RUST_TOOLCHAIN " </dev/null || true
2025-11-13 12:38:04 +01:00
# Ensure PATH is updated for current shell session
export PATH = " $CARGO_BIN : $PATH "
2025-12-15 15:22:32 +01:00
local RUST_VERSION
RUST_VERSION = $( rustc --version 2>/dev/null | awk '{print $2}' 2>/dev/null) || true
2025-11-13 12:38:04 +01:00
if [ [ -z " $RUST_VERSION " ] ] ; then
msg_error "Failed to determine Rust version after update"
return 1
fi
2025-10-22 06:25:26 -07:00
cache_installed_version "rust" " $RUST_VERSION "
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
msg_ok " Update Rust $RUST_VERSION "
2025-05-27 14:29:50 +02:00
fi
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Install global crates
2025-05-27 14:29:50 +02:00
if [ [ -n " $RUST_CRATES " ] ] ; then
2025-11-13 12:38:04 +01:00
msg_info " Processing Rust crates: $RUST_CRATES "
2025-05-27 14:29:50 +02:00
IFS = ',' read -ra CRATES <<< " $RUST_CRATES "
for crate in " ${ CRATES [@] } " ; do
2025-11-13 12:38:04 +01:00
crate = $( echo " $crate " | xargs) # trim whitespace
[ [ -z " $crate " ] ] && continue # skip empty entries
local NAME VER INSTALLED_VER CRATE_LIST
2025-05-27 14:29:50 +02:00
if [ [ " $crate " = = *"@" * ] ] ; then
NAME = " ${ crate %@* } "
VER = " ${ crate ##*@ } "
else
NAME = " $crate "
VER = ""
fi
2025-11-13 12:38:04 +01:00
# Get list of installed crates once
CRATE_LIST = $( cargo install --list 2>/dev/null || echo "" )
# Check if already installed
if echo " $CRATE_LIST " | grep -q " ^ ${ NAME } " ; then
2025-12-18 18:38:08 +01:00
INSTALLED_VER = $( echo " $CRATE_LIST " | grep " ^ ${ NAME } " | head -1 | awk '{print $2}' 2>/dev/null | tr -d 'v:' || echo '' )
2025-05-27 14:29:50 +02:00
if [ [ -n " $VER " && " $VER " != " $INSTALLED_VER " ] ] ; then
2025-11-13 12:38:04 +01:00
msg_info " Upgrading $NAME from v $INSTALLED_VER to v $VER "
$STD cargo install " $NAME " --version " $VER " --force || {
msg_error " Failed to install $NAME @ $VER "
return 1
}
msg_ok " Upgraded $NAME to v $VER "
2025-05-27 14:29:50 +02:00
elif [ [ -z " $VER " ] ] ; then
2025-11-13 12:38:04 +01:00
msg_info " Upgrading $NAME to latest "
$STD cargo install " $NAME " --force || {
msg_error " Failed to upgrade $NAME "
return 1
}
2025-12-18 18:38:08 +01:00
local NEW_VER = $( cargo install --list 2>/dev/null | grep " ^ ${ NAME } " | head -1 | awk '{print $2}' 2>/dev/null | tr -d 'v:' || echo 'unknown' )
2025-11-13 12:38:04 +01:00
msg_ok " Upgraded $NAME to v $NEW_VER "
else
msg_ok " $NAME v $INSTALLED_VER already installed "
2025-05-27 14:29:50 +02:00
fi
else
2025-11-13 12:38:04 +01:00
msg_info " Installing $NAME ${ VER : +@ $VER } "
if [ [ -n " $VER " ] ] ; then
$STD cargo install " $NAME " --version " $VER " || {
msg_error " Failed to install $NAME @ $VER "
return 1
}
msg_ok " Installed $NAME v $VER "
else
$STD cargo install " $NAME " || {
msg_error " Failed to install $NAME "
return 1
}
2025-12-18 18:38:08 +01:00
local NEW_VER = $( cargo install --list 2>/dev/null | grep " ^ ${ NAME } " | head -1 | awk '{print $2}' 2>/dev/null | tr -d 'v:' || echo 'unknown' )
2025-11-13 12:38:04 +01:00
msg_ok " Installed $NAME v $NEW_VER "
fi
2025-05-27 14:29:50 +02:00
fi
done
2025-11-13 12:38:04 +01:00
msg_ok "Processed Rust crates"
2025-05-27 14:29:50 +02:00
fi
}
# ------------------------------------------------------------------------------
2025-09-11 12:44:13 +02:00
# Installs or upgrades uv (Python package manager) from GitHub releases.
# - Downloads platform-specific tarball (no install.sh!)
# - Extracts uv binary
# - Places it in /usr/local/bin
# - Optionally installs a specific Python version via uv
2025-06-18 12:07:08 +02:00
# ------------------------------------------------------------------------------
2025-09-11 12:44:13 +02:00
function setup_uv( ) {
local UV_BIN = "/usr/local/bin/uv"
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
local UVX_BIN = "/usr/local/bin/uvx"
2025-10-22 06:25:26 -07:00
local TMP_DIR = $( mktemp -d)
local CACHED_VERSION
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# trap for TMP Cleanup
trap " rm -rf ' $TMP_DIR ' " EXIT
2025-10-22 06:25:26 -07:00
CACHED_VERSION = $( get_cached_version "uv" )
2025-06-18 12:07:08 +02:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Architecture Detection
2025-10-22 06:25:26 -07:00
local ARCH = $( uname -m)
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
local OS_TYPE = ""
local UV_TAR = ""
if grep -qi "alpine" /etc/os-release; then
OS_TYPE = "musl"
else
OS_TYPE = "gnu"
fi
2025-06-18 12:07:08 +02:00
2025-09-11 12:44:13 +02:00
case " $ARCH " in
x86_64)
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
UV_TAR = " uv-x86_64-unknown-linux- ${ OS_TYPE } .tar.gz "
2025-09-11 12:44:13 +02:00
; ;
aarch64)
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
UV_TAR = " uv-aarch64-unknown-linux- ${ OS_TYPE } .tar.gz "
; ;
i686)
UV_TAR = " uv-i686-unknown-linux- ${ OS_TYPE } .tar.gz "
2025-07-08 17:19:51 +02:00
; ;
*)
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
msg_error " Unsupported architecture: $ARCH (supported: x86_64, aarch64, i686) "
2025-07-08 17:19:51 +02:00
return 1
; ;
esac
2025-10-22 06:25:26 -07:00
ensure_dependencies jq
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Fetch latest version
local releases_json
releases_json = $( curl -fsSL --max-time 15 \
"https://api.github.com/repos/astral-sh/uv/releases/latest" 2>/dev/null || echo "" )
if [ [ -z " $releases_json " ] ] ; then
msg_error "Could not fetch latest uv version from GitHub API"
return 1
fi
2025-09-11 12:44:13 +02:00
local LATEST_VERSION
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
LATEST_VERSION = $( echo " $releases_json " | jq -r '.tag_name' 2>/dev/null | sed 's/^v//' )
2025-07-08 17:19:51 +02:00
2025-09-11 12:44:13 +02:00
if [ [ -z " $LATEST_VERSION " ] ] ; then
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
msg_error "Could not parse uv version from GitHub API response"
2025-07-08 17:19:51 +02:00
return 1
fi
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Get currently installed version
local INSTALLED_VERSION = ""
2025-09-11 12:44:13 +02:00
if [ [ -x " $UV_BIN " ] ] ; then
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
INSTALLED_VERSION = $( " $UV_BIN " --version 2>/dev/null | awk '{print $2}' )
fi
# Scenario 1: Already at latest version
if [ [ -n " $INSTALLED_VERSION " && " $INSTALLED_VERSION " = = " $LATEST_VERSION " ] ] ; then
cache_installed_version "uv" " $LATEST_VERSION "
# Check if uvx is needed and missing
if [ [ " ${ USE_UVX :- NO } " = = "YES" ] ] && [ [ ! -x " $UVX_BIN " ] ] ; then
msg_info "Installing uvx wrapper"
_install_uvx_wrapper || return 1
msg_ok "uvx wrapper installed"
2025-09-11 12:44:13 +02:00
fi
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
return 0
2025-07-08 17:19:51 +02:00
fi
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Scenario 2: New install or upgrade
if [ [ -n " $INSTALLED_VERSION " && " $INSTALLED_VERSION " != " $LATEST_VERSION " ] ] ; then
msg_info " Upgrade uv from $INSTALLED_VERSION to $LATEST_VERSION "
else
msg_info " Setup uv $LATEST_VERSION "
fi
2025-10-22 06:25:26 -07:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
local UV_URL = " https://github.com/astral-sh/uv/releases/download/ ${ LATEST_VERSION } / ${ UV_TAR } "
$STD curl -fsSL " $UV_URL " -o " $TMP_DIR /uv.tar.gz " || {
msg_error " Failed to download uv from $UV_URL "
2025-07-08 17:19:51 +02:00
return 1
2025-10-22 06:25:26 -07:00
}
2025-07-08 17:19:51 +02:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Extract
$STD tar -xzf " $TMP_DIR /uv.tar.gz " -C " $TMP_DIR " || {
2025-10-22 06:25:26 -07:00
msg_error "Failed to extract uv"
2025-07-08 17:19:51 +02:00
return 1
2025-10-22 06:25:26 -07:00
}
2025-07-08 17:19:51 +02:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Find and install uv binary (tarball extracts to uv-VERSION-ARCH/ directory)
local UV_BINARY = $( find " $TMP_DIR " -name "uv" -type f -executable | head -n1)
if [ [ ! -f " $UV_BINARY " ] ] ; then
msg_error "Could not find uv binary in extracted tarball"
return 1
fi
$STD install -m 755 " $UV_BINARY " " $UV_BIN " || {
2025-09-11 12:44:13 +02:00
msg_error "Failed to install uv binary"
2025-07-08 17:19:51 +02:00
return 1
}
ensure_usr_local_bin_persist
2025-10-22 06:25:26 -07:00
export PATH = " /usr/local/bin: $PATH "
2025-09-23 11:39:46 +02:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Optional: Install uvx wrapper
if [ [ " ${ USE_UVX :- NO } " = = "YES" ] ] ; then
msg_info "Installing uvx wrapper"
_install_uvx_wrapper || {
msg_error "Failed to install uvx wrapper"
return 1
}
msg_ok "uvx wrapper installed"
fi
# Optional: Generate shell completions
$STD uv generate-shell-completion bash >/etc/bash_completion.d/uv 2>/dev/null || true
2025-11-12 09:56:24 +01:00
if [ [ -d /usr/share/zsh/site-functions ] ] ; then
$STD uv generate-shell-completion zsh >/usr/share/zsh/site-functions/_uv 2>/dev/null || true
fi
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Optional: Install specific Python version if requested
if [ [ -n " ${ PYTHON_VERSION :- } " ] ] ; then
msg_info " Installing Python $PYTHON_VERSION via uv "
$STD uv python install " $PYTHON_VERSION " || {
msg_error " Failed to install Python $PYTHON_VERSION "
return 1
}
msg_ok " Python $PYTHON_VERSION installed "
fi
2025-10-22 06:25:26 -07:00
cache_installed_version "uv" " $LATEST_VERSION "
2025-09-11 12:44:13 +02:00
msg_ok " Setup uv $LATEST_VERSION "
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
}
2025-09-11 12:44:13 +02:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Helper function to install uvx wrapper
_install_uvx_wrapper( ) {
local UVX_BIN = "/usr/local/bin/uvx"
2025-09-11 12:44:13 +02:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
cat >" $UVX_BIN " <<'EOF'
#!/bin/bash
# uvx - Run Python applications from PyPI as command-line tools
# Wrapper for: uv tool run
exec /usr/local/bin/uv tool run " $@ "
EOF
2025-09-11 12:44:13 +02:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
chmod +x " $UVX_BIN "
return 0
2025-07-08 17:19:51 +02:00
}
2025-08-28 14:43:56 +02:00
# ------------------------------------------------------------------------------
2025-09-11 12:44:13 +02:00
# Installs or updates yq (mikefarah/yq - Go version).
2025-08-28 14:43:56 +02:00
#
# Description:
2025-09-11 12:44:13 +02:00
# - Checks if yq is installed and from correct source
# - Compares with latest release on GitHub
# - Updates if outdated or wrong implementation
2025-08-28 14:43:56 +02:00
# ------------------------------------------------------------------------------
2025-09-11 12:44:13 +02:00
function setup_yq( ) {
2025-10-22 06:25:26 -07:00
local TMP_DIR = $( mktemp -d)
2025-09-11 12:44:13 +02:00
local BINARY_PATH = "/usr/local/bin/yq"
local GITHUB_REPO = "mikefarah/yq"
2025-08-28 14:43:56 +02:00
2025-10-22 06:25:26 -07:00
ensure_dependencies jq
ensure_usr_local_bin_persist
2025-09-23 14:00:48 -04:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Remove non-mikefarah implementations
2025-09-11 12:44:13 +02:00
if command -v yq & >/dev/null; then
if ! yq --version 2>& 1 | grep -q 'mikefarah' ; then
rm -f " $( command -v yq) "
fi
2025-09-01 09:38:20 +02:00
fi
2025-08-29 12:29:52 +02:00
2025-09-11 12:44:13 +02:00
local LATEST_VERSION
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
local releases_json
releases_json = $( curl -fsSL --max-time 15 " https://api.github.com/repos/ ${ GITHUB_REPO } /releases/latest " 2>/dev/null || echo "" )
if [ [ -z " $releases_json " ] ] ; then
msg_error "Could not fetch latest yq version from GitHub API"
rm -rf " $TMP_DIR "
return 1
fi
LATEST_VERSION = $( echo " $releases_json " | jq -r '.tag_name' 2>/dev/null | sed 's/^v//' || echo "" )
2025-08-29 14:20:12 +02:00
2025-09-11 12:44:13 +02:00
if [ [ -z " $LATEST_VERSION " ] ] ; then
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
msg_error "Could not parse yq version from GitHub API response"
2025-09-11 12:44:13 +02:00
rm -rf " $TMP_DIR "
return 1
2025-09-01 09:38:20 +02:00
fi
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Get currently installed version
local INSTALLED_VERSION = ""
if command -v yq & >/dev/null && yq --version 2>& 1 | grep -q 'mikefarah' ; then
INSTALLED_VERSION = $( yq --version 2>/dev/null | awk '{print $NF}' | sed 's/^v//' )
fi
# Scenario 1: Already at latest version
if [ [ -n " $INSTALLED_VERSION " && " $INSTALLED_VERSION " = = " $LATEST_VERSION " ] ] ; then
2025-10-22 06:25:26 -07:00
cache_installed_version "yq" " $LATEST_VERSION "
rm -rf " $TMP_DIR "
return 0
2025-09-11 12:44:13 +02:00
fi
2025-08-29 14:20:12 +02:00
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
# Scenario 2: New install or upgrade
if [ [ -n " $INSTALLED_VERSION " && " $INSTALLED_VERSION " != " $LATEST_VERSION " ] ] ; then
msg_info " Upgrade yq from $INSTALLED_VERSION to $LATEST_VERSION "
else
msg_info " Setup yq $LATEST_VERSION "
fi
2025-10-22 06:25:26 -07:00
curl -fsSL " https://github.com/ ${ GITHUB_REPO } /releases/download/v ${ LATEST_VERSION } /yq_linux_amd64 " -o " $TMP_DIR /yq " || {
msg_error "Failed to download yq"
rm -rf " $TMP_DIR "
return 1
}
2025-09-11 12:44:13 +02:00
chmod +x " $TMP_DIR /yq "
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
mv " $TMP_DIR /yq " " $BINARY_PATH " || {
2025-10-22 06:25:26 -07:00
msg_error "Failed to install yq"
2025-09-11 12:44:13 +02:00
rm -rf " $TMP_DIR "
2025-08-29 16:20:21 +02:00
return 1
Refactor(tools.func): Add Retry Logic, OS-Upgrade Safety, Smart Version Detection + 10 Critical Bugfixes (#8871)
* Add robust package and repository management helpers
Introduces unified helper functions for package installation, repository management, and legacy cleanup across Debian/Ubuntu upgrades. Adds retry logic for APT operations, keyring cleanup, service management, version checks, and tool-specific repository setup. Refactors setup functions for Composer, FFmpeg, Go, Ghostscript, ImageMagick, Java, hardware acceleration, and MariaDB to use new helpers, improving reliability and upgrade safety.
* english comment
2025-11-05 05:19:35 -08:00
}
2025-08-28 14:43:56 +02:00
2025-09-11 12:44:13 +02:00
rm -rf " $TMP_DIR "
hash -r
2025-08-29 16:20:21 +02:00
2025-09-11 12:44:13 +02:00
local FINAL_VERSION
2025-10-22 06:25:26 -07:00
FINAL_VERSION = $( " $BINARY_PATH " --version 2>/dev/null | awk '{print $NF}' | sed 's/^v//' )
cache_installed_version "yq" " $FINAL_VERSION "
msg_ok " Setup yq $FINAL_VERSION "
2025-08-28 14:43:56 +02:00
}
Three-tier defaults system | security improvements | error_handler | improved logging | improved container creation | improved architecture (#9540)
* Refactor Core
Refactored misc/alpine-install.func to improve error handling, network checks, and MOTD setup. Added misc/alpine-tools.func and misc/error_handler.func for modular tool installation and error management. Enhanced misc/api.func with detailed exit code explanations and telemetry functions. Updated misc/core.func for better initialization, validation, and execution helpers. Removed misc/create_lxc.sh as part of cleanup.
* Delete config-file.func
* Update install.func
* Refactor stop_all_services function and variable names
Refactor service stopping logic and improve variable handling
* Refactor installation script and update copyright
Updated copyright information and adjusted package installation commands. Enhanced IPv6 disabling logic and improved container customization process.
* Update install.func
* Update license comment format in install.func
* Refactor IPv6 handling and enhance MOTD and SSH
Refactor IPv6 handling and update OS function. Enhance MOTD with additional details and configure SSH settings.
* big core refactor
* Enhance IPv6 configuration menu options
Updated IPv6 Address Management menu options for clarity and added a new option for fully disabling IPv6.
* Update default Node.js version to 24 LTS
* Update misc/alpine-tools.func
Co-authored-by: Michel Roegl-Brunner <73236783+michelroegl-brunner@users.noreply.github.com>
* indention
* remove debugf and duplicate codes
* Update whiptail backtitles and error codes
Removed '[dev]' from whiptail --backtitle strings for consistency. Refactored custom exit codes in build.func and error_handler.func: updated Proxmox error codes, shifted MySQL/MariaDB codes to 260-263, and removed unused MongoDB code. Updated error descriptions to match new codes.
* comments
* Refactor error handling and clean up debug comments
Standardized bash variable checks, removed unnecessary debug and commented code, and clarified error handling logic in container build and setup scripts. These changes improve code readability and maintainability without altering functional behavior.
* Update build.func
* feat: Improve LXC network checks and LINSTOR storage handling
Enhanced LXC container network setup to check for both IPv4 and IPv6 addresses, added connectivity (ping) tests, and provided troubleshooting tips on failure. Updated storage validation to support LINSTOR, including cluster connectivity checks and special handling for LINSTOR template storage.
---------
Co-authored-by: Michel Roegl-Brunner <73236783+michelroegl-brunner@users.noreply.github.com>
2025-12-04 07:52:18 +01:00
# ------------------------------------------------------------------------------
# Docker Engine Installation and Management (All-In-One)
#
# Description:
# - Detects and migrates old Docker installations
# - Installs/Updates Docker Engine via official repository
# - Optional: Installs/Updates Portainer CE
# - Updates running containers interactively
# - Cleans up legacy repository files
#
# Usage:
# setup_docker
# DOCKER_PORTAINER="true" setup_docker
# DOCKER_LOG_DRIVER="json-file" setup_docker
#
# Variables:
# DOCKER_PORTAINER - Install Portainer CE (optional, "true" to enable)
# DOCKER_LOG_DRIVER - Log driver (optional, default: "journald")
# DOCKER_SKIP_UPDATES - Skip container update check (optional, "true" to skip)
#
# Features:
# - Migrates from get.docker.com to repository-based installation
# - Updates Docker Engine if newer version available
# - Interactive container update with multi-select
# - Portainer installation and update support
# ------------------------------------------------------------------------------
function setup_docker( ) {
local docker_installed = false
local portainer_installed = false
# Check if Docker is already installed
if command -v docker & >/dev/null; then
docker_installed = true
DOCKER_CURRENT_VERSION = $( docker --version | grep -oP '\d+\.\d+\.\d+' | head -1)
msg_info " Docker $DOCKER_CURRENT_VERSION detected "
fi
# Check if Portainer is running
if docker ps --format '{{.Names}}' 2>/dev/null | grep -q '^portainer$' ; then
portainer_installed = true
msg_info "Portainer container detected"
fi
# Cleanup old repository configurations
if [ -f /etc/apt/sources.list.d/docker.list ] ; then
msg_info "Migrating from old Docker repository format"
rm -f /etc/apt/sources.list.d/docker.list
rm -f /etc/apt/keyrings/docker.asc
fi
# Setup/Update Docker repository
msg_info "Setting up Docker Repository"
setup_deb822_repo \
"docker" \
" https://download.docker.com/linux/ $( get_os_info id) /gpg " \
" https://download.docker.com/linux/ $( get_os_info id) " \
" $( get_os_info codename) " \
"stable" \
" $( dpkg --print-architecture) "
# Install or upgrade Docker
if [ " $docker_installed " = true ] ; then
msg_info "Checking for Docker updates"
2025-12-18 18:38:08 +01:00
DOCKER_LATEST_VERSION = $( apt-cache policy docker-ce | grep Candidate | awk '{print $2}' 2>/dev/null | cut -d':' -f2 | cut -d'-' -f1 || echo '' )
Three-tier defaults system | security improvements | error_handler | improved logging | improved container creation | improved architecture (#9540)
* Refactor Core
Refactored misc/alpine-install.func to improve error handling, network checks, and MOTD setup. Added misc/alpine-tools.func and misc/error_handler.func for modular tool installation and error management. Enhanced misc/api.func with detailed exit code explanations and telemetry functions. Updated misc/core.func for better initialization, validation, and execution helpers. Removed misc/create_lxc.sh as part of cleanup.
* Delete config-file.func
* Update install.func
* Refactor stop_all_services function and variable names
Refactor service stopping logic and improve variable handling
* Refactor installation script and update copyright
Updated copyright information and adjusted package installation commands. Enhanced IPv6 disabling logic and improved container customization process.
* Update install.func
* Update license comment format in install.func
* Refactor IPv6 handling and enhance MOTD and SSH
Refactor IPv6 handling and update OS function. Enhance MOTD with additional details and configure SSH settings.
* big core refactor
* Enhance IPv6 configuration menu options
Updated IPv6 Address Management menu options for clarity and added a new option for fully disabling IPv6.
* Update default Node.js version to 24 LTS
* Update misc/alpine-tools.func
Co-authored-by: Michel Roegl-Brunner <73236783+michelroegl-brunner@users.noreply.github.com>
* indention
* remove debugf and duplicate codes
* Update whiptail backtitles and error codes
Removed '[dev]' from whiptail --backtitle strings for consistency. Refactored custom exit codes in build.func and error_handler.func: updated Proxmox error codes, shifted MySQL/MariaDB codes to 260-263, and removed unused MongoDB code. Updated error descriptions to match new codes.
* comments
* Refactor error handling and clean up debug comments
Standardized bash variable checks, removed unnecessary debug and commented code, and clarified error handling logic in container build and setup scripts. These changes improve code readability and maintainability without altering functional behavior.
* Update build.func
* feat: Improve LXC network checks and LINSTOR storage handling
Enhanced LXC container network setup to check for both IPv4 and IPv6 addresses, added connectivity (ping) tests, and provided troubleshooting tips on failure. Updated storage validation to support LINSTOR, including cluster connectivity checks and special handling for LINSTOR template storage.
---------
Co-authored-by: Michel Roegl-Brunner <73236783+michelroegl-brunner@users.noreply.github.com>
2025-12-04 07:52:18 +01:00
if [ " $DOCKER_CURRENT_VERSION " != " $DOCKER_LATEST_VERSION " ] ; then
msg_info " Updating Docker $DOCKER_CURRENT_VERSION → $DOCKER_LATEST_VERSION "
$STD apt install -y --only-upgrade \
docker-ce \
docker-ce-cli \
containerd.io \
docker-buildx-plugin \
docker-compose-plugin
msg_ok " Updated Docker to $DOCKER_LATEST_VERSION "
else
msg_ok " Docker is up-to-date ( $DOCKER_CURRENT_VERSION ) "
fi
else
msg_info "Installing Docker"
$STD apt install -y \
docker-ce \
docker-ce-cli \
containerd.io \
docker-buildx-plugin \
docker-compose-plugin
DOCKER_CURRENT_VERSION = $( docker --version | grep -oP '\d+\.\d+\.\d+' | head -1)
msg_ok " Installed Docker $DOCKER_CURRENT_VERSION "
fi
# Configure daemon.json
local log_driver = " ${ DOCKER_LOG_DRIVER :- journald } "
mkdir -p /etc/docker
if [ ! -f /etc/docker/daemon.json ] ; then
cat <<EOF >/etc/docker/daemon.json
{
"log-driver" : " $log_driver "
}
EOF
fi
# Enable and start Docker
systemctl enable -q --now docker
# Portainer Management
if [ [ " ${ DOCKER_PORTAINER :- } " = = "true" ] ] ; then
if [ " $portainer_installed " = true ] ; then
msg_info "Checking for Portainer updates"
PORTAINER_CURRENT = $( docker inspect portainer --format= '{{.Config.Image}}' 2>/dev/null | cut -d':' -f2)
PORTAINER_LATEST = $( curl -fsSL https://registry.hub.docker.com/v2/repositories/portainer/portainer-ce/tags?page_size= 100 | grep -oP '"name":"\K[0-9]+\.[0-9]+\.[0-9]+"' | head -1 | tr -d '"' )
if [ " $PORTAINER_CURRENT " != " $PORTAINER_LATEST " ] ; then
read -r -p " ${ TAB3 } Update Portainer $PORTAINER_CURRENT → $PORTAINER_LATEST ? <y/N> " prompt
if [ [ ${ prompt ,, } = ~ ^( y| yes) $ ] ] ; then
msg_info "Updating Portainer"
docker stop portainer
docker rm portainer
docker pull portainer/portainer-ce:latest
docker run -d \
-p 9000:9000 \
-p 9443:9443 \
--name= portainer \
--restart= always \
-v /var/run/docker.sock:/var/run/docker.sock \
-v portainer_data:/data \
portainer/portainer-ce:latest
msg_ok " Updated Portainer to $PORTAINER_LATEST "
fi
else
msg_ok " Portainer is up-to-date ( $PORTAINER_CURRENT ) "
fi
else
msg_info "Installing Portainer"
docker volume create portainer_data
docker run -d \
-p 9000:9000 \
-p 9443:9443 \
--name= portainer \
--restart= always \
-v /var/run/docker.sock:/var/run/docker.sock \
-v portainer_data:/data \
portainer/portainer-ce:latest
LOCAL_IP = $( hostname -I | awk '{print $1}' )
msg_ok " Installed Portainer (http:// ${ LOCAL_IP } :9000) "
fi
fi
# Interactive Container Update Check
if [ [ " ${ DOCKER_SKIP_UPDATES :- } " != "true" ] ] && [ " $docker_installed " = true ] ; then
msg_info "Checking for container updates"
# Get list of running containers with update status
local containers_with_updates = ( )
local container_info = ( )
local index = 1
while IFS = read -r container; do
local name = $( echo " $container " | awk '{print $1}' )
local image = $( echo " $container " | awk '{print $2}' )
local current_digest = $( docker inspect " $name " --format= '{{.Image}}' 2>/dev/null | cut -d':' -f2 | cut -c1-12)
# Pull latest image digest
docker pull " $image " >/dev/null 2>& 1
local latest_digest = $( docker inspect " $image " --format= '{{.Id}}' 2>/dev/null | cut -d':' -f2 | cut -c1-12)
if [ " $current_digest " != " $latest_digest " ] ; then
containers_with_updates += ( " $name " )
container_info += ( " ${ index } ) ${ name } ( ${ image } ) " )
( ( index++) )
fi
done < <( docker ps --format '{{.Names}} {{.Image}}' )
if [ ${# containers_with_updates [@] } -gt 0 ] ; then
echo ""
echo " ${ TAB3 } Container updates available: "
for info in " ${ container_info [@] } " ; do
echo " ${ TAB3 } $info "
done
echo ""
read -r -p " ${ TAB3 } Select containers to update (e.g., 1,3,5 or 'all' or 'none'): " selection
if [ [ ${ selection ,, } = = "all" ] ] ; then
for container in " ${ containers_with_updates [@] } " ; do
msg_info " Updating container: $container "
docker stop " $container "
docker rm " $container "
# Note: This requires the original docker run command - best to recreate via compose
msg_ok " Stopped and removed $container (please recreate with updated image) "
done
elif [ [ ${ selection ,, } != "none" ] ] ; then
IFS = ',' read -ra SELECTED <<< " $selection "
for num in " ${ SELECTED [@] } " ; do
num = $( echo " $num " | xargs) # trim whitespace
if [ [ " $num " = ~ ^[ 0-9] +$ ] ] && [ " $num " -ge 1 ] && [ " $num " -le " ${# containers_with_updates [@] } " ] ; then
container = " ${ containers_with_updates [ $(( num - 1 )) ] } "
msg_info " Updating container: $container "
docker stop " $container "
docker rm " $container "
msg_ok " Stopped and removed $container (please recreate with updated image) "
fi
done
fi
else
msg_ok "All containers are up-to-date"
fi
fi
msg_ok "Docker setup completed"
}
2026-01-30 22:25:55 +01:00
# ------------------------------------------------------------------------------
# Fetch and deploy from URL
# Downloads an archive (zip, tar.gz, or .deb) from a URL and extracts/installs it
#
# Usage: fetch_and_deploy_from_url "url" "directory"
# url - URL to the archive (zip, tar.gz, or .deb)
# directory - Destination path where the archive will be extracted
# (not used for .deb packages)
#
# Examples:
# fetch_and_deploy_from_url "https://example.com/app.tar.gz" "/opt/myapp"
# fetch_and_deploy_from_url "https://example.com/app.zip" "/opt/myapp"
# fetch_and_deploy_from_url "https://example.com/package.deb" ""
# ------------------------------------------------------------------------------
function fetch_and_deploy_from_url( ) {
local url = " $1 "
local directory = " $2 "
if [ [ -z " $url " ] ] ; then
msg_error "URL parameter is required"
return 1
fi
local filename = " ${ url ##*/ } "
msg_info " Downloading from $url "
local tmpdir
tmpdir = $( mktemp -d) || {
msg_error "Failed to create temporary directory"
return 1
}
curl -fsSL -o " $tmpdir / $filename " " $url " || {
msg_error " Download failed: $url "
rm -rf " $tmpdir "
return 1
}
2026-02-01 13:19:11 +01:00
# Auto-detect archive type using file description
local file_desc
file_desc = $( file -b " $tmpdir / $filename " )
2026-02-22 11:54:21 +01:00
2026-02-01 13:19:11 +01:00
local archive_type = "unknown"
2026-02-22 11:54:21 +01:00
2026-02-01 13:19:11 +01:00
if [ [ " $file_desc " = ~ gzip.*compressed| gzip\ compressed\ data ] ] ; then
archive_type = "tar"
elif [ [ " $file_desc " = ~ Zip.*archive| ZIP\ archive ] ] ; then
archive_type = "zip"
elif [ [ " $file_desc " = ~ Debian.*package| Debian\ binary\ package ] ] ; then
archive_type = "deb"
elif [ [ " $file_desc " = ~ POSIX.*tar.*archive| tar\ archive ] ] ; then
archive_type = "tar"
else
msg_error " Unsupported or unknown archive type: $file_desc "
rm -rf " $tmpdir "
return 1
fi
msg_info " Detected archive type: $archive_type (file type: $file_desc ) "
2026-01-30 22:25:55 +01:00
if [ [ " $archive_type " = = "deb" ] ] ; then
msg_info "Installing .deb package"
chmod 644 " $tmpdir / $filename "
$STD apt install -y " $tmpdir / $filename " || {
$STD dpkg -i " $tmpdir / $filename " || {
msg_error "Both apt and dpkg installation failed"
rm -rf " $tmpdir "
return 1
}
}
rm -rf " $tmpdir "
msg_ok "Successfully installed .deb package"
return 0
fi
if [ [ -z " $directory " ] ] ; then
msg_error "Directory parameter is required for archive extraction"
rm -rf " $tmpdir "
return 1
fi
msg_info " Extracting archive to $directory "
mkdir -p " $directory "
if [ [ " ${ CLEAN_INSTALL :- 0 } " = = "1" ] ] ; then
rm -rf " ${ directory : ? } / " *
fi
local unpack_tmp
unpack_tmp = $( mktemp -d)
if [ [ " $archive_type " = = "zip" ] ] ; then
ensure_dependencies unzip
unzip -q " $tmpdir / $filename " -d " $unpack_tmp " || {
msg_error "Failed to extract ZIP archive"
rm -rf " $tmpdir " " $unpack_tmp "
return 1
}
elif [ [ " $archive_type " = = "tar" ] ] ; then
tar --no-same-owner -xf " $tmpdir / $filename " -C " $unpack_tmp " || {
msg_error "Failed to extract TAR archive"
rm -rf " $tmpdir " " $unpack_tmp "
return 1
}
fi
local top_entries
top_entries = $( find " $unpack_tmp " -mindepth 1 -maxdepth 1)
if [ [ " $( echo " $top_entries " | wc -l) " -eq 1 && -d " $top_entries " ] ] ; then
local inner_dir = " $top_entries "
shopt -s dotglob nullglob
if compgen -G " $inner_dir /* " >/dev/null; then
cp -r " $inner_dir " /* " $directory / " || {
msg_error " Failed to copy contents from $inner_dir to $directory "
rm -rf " $tmpdir " " $unpack_tmp "
return 1
}
else
msg_error " Inner directory is empty: $inner_dir "
rm -rf " $tmpdir " " $unpack_tmp "
return 1
fi
shopt -u dotglob nullglob
else
shopt -s dotglob nullglob
if compgen -G " $unpack_tmp /* " >/dev/null; then
cp -r " $unpack_tmp " /* " $directory / " || {
msg_error " Failed to copy contents to $directory "
rm -rf " $tmpdir " " $unpack_tmp "
return 1
}
else
msg_error "Unpacked archive is empty"
rm -rf " $tmpdir " " $unpack_tmp "
return 1
fi
shopt -u dotglob nullglob
fi
rm -rf " $tmpdir " " $unpack_tmp "
msg_ok " Successfully deployed archive to $directory "
return 0
}