mirror of
https://github.com/community-scripts/ProxmoxVE.git
synced 2026-06-21 23:11:18 +02:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 73c55bed9f | |||
| f7210f3a66 | |||
| 8b877f1c9f | |||
| 6192225be7 | |||
| 6665a5bf5d | |||
| 53efcadfa9 |
@@ -500,6 +500,14 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
|
||||
|
||||
- tools.func: centralize Node.js corepack and npm handling in `setup_nodejs()` [@MickLesk](https://github.com/MickLesk) ([#15268](https://github.com/community-scripts/ProxmoxVE/pull/15268))
|
||||
|
||||
### 💾 Core
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- tools.func: APT install and deb822 repo reliability [@MickLesk](https://github.com/MickLesk) ([#15272](https://github.com/community-scripts/ProxmoxVE/pull/15272))
|
||||
- tools.func: prevent MySQL data loss and fix repo version matching [@MickLesk](https://github.com/MickLesk) ([#15271](https://github.com/community-scripts/ProxmoxVE/pull/15271))
|
||||
- tools.func: runtime hardening for API helpers and Docker/MeiliSearch [@MickLesk](https://github.com/MickLesk) ([#15273](https://github.com/community-scripts/ProxmoxVE/pull/15273))
|
||||
|
||||
## 2026-06-20
|
||||
|
||||
### 🆕 New Scripts
|
||||
|
||||
+121
-21
@@ -24,6 +24,7 @@
|
||||
# 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
|
||||
# version_matches_spec() - Compare installed semver against spec (8.0 matches 8.0.40)
|
||||
# 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
|
||||
@@ -282,7 +283,7 @@ get_cached_version() {
|
||||
cat "/var/cache/app-versions/${app}_version.txt"
|
||||
return 0
|
||||
fi
|
||||
return 0
|
||||
return 1
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
@@ -344,6 +345,37 @@ verify_tool_version() {
|
||||
return 0
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Compare installed semver against a version spec at the spec's precision.
|
||||
# Returns: 0 if match (e.g. spec 8.0 matches installed 8.0.40), 1 otherwise
|
||||
# Usage: version_matches_spec "8.0.40" "8.0"
|
||||
# ------------------------------------------------------------------------------
|
||||
version_matches_spec() {
|
||||
local installed="$1"
|
||||
local spec="$2"
|
||||
local spec_depth prefix i
|
||||
local -a spec_parts installed_parts
|
||||
|
||||
[[ -n "$installed" && -n "$spec" ]] || return 1
|
||||
|
||||
IFS='.' read -ra spec_parts <<<"$spec"
|
||||
spec_depth=${#spec_parts[@]}
|
||||
((spec_depth > 0)) || return 1
|
||||
|
||||
if ((spec_depth == 1)); then
|
||||
[[ "${installed%%.*}" == "$spec" ]] && return 0
|
||||
return 1
|
||||
fi
|
||||
|
||||
IFS='.' read -ra installed_parts <<<"$installed"
|
||||
prefix=""
|
||||
for ((i = 0; i < spec_depth && i < ${#installed_parts[@]}; i++)); do
|
||||
[[ -n "$prefix" ]] && prefix+="."
|
||||
prefix+="${installed_parts[i]}"
|
||||
done
|
||||
[[ "$prefix" == "$spec" ]]
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Clean up legacy installation methods (nvm, rbenv, rustup, etc.)
|
||||
# Usage: cleanup_legacy_install "nodejs" -> removes nvm
|
||||
@@ -462,10 +494,10 @@ install_packages_with_retry() {
|
||||
fi
|
||||
fi
|
||||
done
|
||||
# If some packages installed, consider partial success
|
||||
if [[ ${#failed[@]} -lt ${#packages[@]} ]]; then
|
||||
if [[ ${#failed[@]} -gt 0 ]]; then
|
||||
msg_warn "Partially installed. Failed packages: ${failed[*]}"
|
||||
msg_error "Partial install — failed packages: ${failed[*]}"
|
||||
return 100
|
||||
fi
|
||||
return 0
|
||||
fi
|
||||
@@ -620,13 +652,15 @@ remove_old_tool_version() {
|
||||
mysql)
|
||||
stop_all_services "mysql"
|
||||
$STD apt purge -y 'mysql*' >/dev/null 2>&1 || true
|
||||
rm -rf /var/lib/mysql 2>/dev/null || true
|
||||
# Keep data directory for safety (remove manually if needed)
|
||||
# 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
|
||||
# Keep data directory for safety (remove manually if needed)
|
||||
# rm -rf /var/lib/mongodb 2>/dev/null || true
|
||||
cleanup_tool_keyrings "mongodb"
|
||||
;;
|
||||
node | nodejs)
|
||||
@@ -671,7 +705,8 @@ remove_old_tool_version() {
|
||||
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
|
||||
# Keep data directory for safety (remove manually if needed)
|
||||
# rm -rf /var/lib/clickhouse 2>/dev/null || true
|
||||
cleanup_tool_keyrings "clickhouse"
|
||||
;;
|
||||
esac
|
||||
@@ -695,8 +730,8 @@ should_update_tool() {
|
||||
# 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
|
||||
# If versions match at the requested precision, no update needed
|
||||
if version_matches_spec "$current_version" "$target_version"; then
|
||||
return 1 # No update needed
|
||||
fi
|
||||
|
||||
@@ -891,6 +926,49 @@ Suites: $distro_codename
|
||||
Components: main
|
||||
Architectures: $(dpkg --print-architecture)
|
||||
Signed-By: /usr/share/keyrings/deb.sury.org-php.gpg
|
||||
EOF
|
||||
return 0
|
||||
;;
|
||||
|
||||
mysql)
|
||||
if [[ -z "$gpg_key_url" ]]; then
|
||||
msg_error "MySQL repository requires gpg_key_url"
|
||||
return 65
|
||||
fi
|
||||
|
||||
cleanup_old_repo_files "mysql"
|
||||
|
||||
if ! download_gpg_key "$gpg_key_url" "/etc/apt/keyrings/mysql.gpg" "dearmor"; then
|
||||
msg_error "Failed to import MySQL GPG key"
|
||||
return 7
|
||||
fi
|
||||
|
||||
local distro_codename suite component
|
||||
distro_codename=$(get_os_info codename)
|
||||
|
||||
if [[ "$distro_id" == "debian" ]]; then
|
||||
case "$distro_codename" in
|
||||
trixie | forky | sid) suite="bookworm" ;;
|
||||
bookworm | bullseye) suite="$distro_codename" ;;
|
||||
*) suite="bookworm" ;;
|
||||
esac
|
||||
else
|
||||
suite=$(get_fallback_suite "$distro_id" "$distro_codename" "$repo_url")
|
||||
fi
|
||||
|
||||
case "$version" in
|
||||
8.4 | 8.4.*) component="mysql-8.4-lts" ;;
|
||||
8.0 | 8.0.*) component="mysql-8.0" ;;
|
||||
*) component="mysql-${version}" ;;
|
||||
esac
|
||||
|
||||
cat <<EOF >/etc/apt/sources.list.d/mysql.sources
|
||||
Types: deb
|
||||
URIs: ${repo_url}/
|
||||
Suites: ${suite}
|
||||
Components: ${component}
|
||||
Architectures: $(dpkg --print-architecture)
|
||||
Signed-By: /etc/apt/keyrings/mysql.gpg
|
||||
EOF
|
||||
return 0
|
||||
;;
|
||||
@@ -1122,11 +1200,34 @@ get_system_arch() {
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Create temporary directory with automatic cleanup
|
||||
# Appends to a shared list so existing EXIT traps are preserved.
|
||||
# ------------------------------------------------------------------------------
|
||||
_tools_temp_dirs=()
|
||||
|
||||
_tools_cleanup_temp_dirs() {
|
||||
local d
|
||||
for d in "${_tools_temp_dirs[@]}"; do
|
||||
rm -rf "$d" 2>/dev/null || true
|
||||
done
|
||||
}
|
||||
|
||||
_tools_register_temp_cleanup() {
|
||||
[[ "${_TOOLS_TEMP_TRAP_SET:-}" == "1" ]] && return 0
|
||||
_TOOLS_TEMP_TRAP_SET=1
|
||||
local existing
|
||||
existing=$(trap -p EXIT 2>/dev/null | sed -n "s/^trap -- '\\(.*\\)' EXIT/\1/p" || true)
|
||||
if [[ -n "$existing" && "$existing" != "_tools_cleanup_temp_dirs" ]]; then
|
||||
trap "_tools_cleanup_temp_dirs; ${existing}" EXIT ERR INT TERM
|
||||
else
|
||||
trap _tools_cleanup_temp_dirs EXIT ERR INT TERM
|
||||
fi
|
||||
}
|
||||
|
||||
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
|
||||
local tmp_dir
|
||||
tmp_dir=$(mktemp -d) || return 1
|
||||
_tools_temp_dirs+=("$tmp_dir")
|
||||
_tools_register_temp_cleanup
|
||||
echo "$tmp_dir"
|
||||
}
|
||||
|
||||
@@ -2049,9 +2150,11 @@ setup_deb822_repo() {
|
||||
[[ -n "$enabled" ]] && echo "Enabled: $enabled"
|
||||
} >/etc/apt/sources.list.d/${name}.sources
|
||||
|
||||
$STD apt update || {
|
||||
msg_warn "apt update failed after adding repository: ${name}"
|
||||
}
|
||||
if ! $STD apt update; then
|
||||
msg_error "apt update failed after adding repository: ${name}"
|
||||
msg_error "Hint: Verify suite '${suite}' and URI '${repo_url}' are valid for this distribution."
|
||||
return 100
|
||||
fi
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
@@ -6432,7 +6535,7 @@ EOF
|
||||
fi
|
||||
|
||||
# Scenario 1: Already installed at target version - just update packages
|
||||
if [[ -n "$CURRENT_VERSION" && "$CURRENT_VERSION" == "$MARIADB_VERSION" ]]; then
|
||||
if [[ -n "$CURRENT_VERSION" ]] && version_matches_spec "$CURRENT_VERSION" "$MARIADB_VERSION"; then
|
||||
msg_info "Update MariaDB $MARIADB_VERSION"
|
||||
|
||||
# Ensure APT is working
|
||||
@@ -6464,7 +6567,7 @@ EOF
|
||||
fi
|
||||
|
||||
# Scenario 2b: Different version installed - clean upgrade
|
||||
if [[ -n "$CURRENT_VERSION" && "$CURRENT_VERSION" != "$MARIADB_VERSION" ]]; then
|
||||
if [[ -n "$CURRENT_VERSION" ]] && ! version_matches_spec "$CURRENT_VERSION" "$MARIADB_VERSION"; then
|
||||
msg_info "Upgrade MariaDB from $CURRENT_VERSION to $MARIADB_VERSION"
|
||||
remove_old_tool_version "mariadb"
|
||||
fi
|
||||
@@ -7168,7 +7271,7 @@ setup_mysql() {
|
||||
|
||||
# Scenario 2: Use official MySQL repository (USE_MYSQL_REPO=true)
|
||||
# Scenario 2a: Already at target version - just update packages
|
||||
if [[ -n "$CURRENT_VERSION" && "$CURRENT_VERSION" == "$MYSQL_VERSION" ]]; then
|
||||
if [[ -n "$CURRENT_VERSION" ]] && version_matches_spec "$CURRENT_VERSION" "$MYSQL_VERSION"; then
|
||||
msg_info "Update MySQL $MYSQL_VERSION"
|
||||
|
||||
ensure_apt_working || return 100
|
||||
@@ -7184,7 +7287,7 @@ setup_mysql() {
|
||||
fi
|
||||
|
||||
# Scenario 2: Different version installed - clean upgrade
|
||||
if [[ -n "$CURRENT_VERSION" && "$CURRENT_VERSION" != "$MYSQL_VERSION" ]]; then
|
||||
if [[ -n "$CURRENT_VERSION" ]] && ! version_matches_spec "$CURRENT_VERSION" "$MYSQL_VERSION"; then
|
||||
msg_info "Upgrade MySQL from $CURRENT_VERSION to $MYSQL_VERSION"
|
||||
remove_old_tool_version "mysql"
|
||||
else
|
||||
@@ -8574,13 +8677,10 @@ setup_uv() {
|
||||
local UV_BIN="/usr/local/bin/uv"
|
||||
local UVX_BIN="/usr/local/bin/uvx"
|
||||
local TMP_DIR=$(mktemp -d)
|
||||
local CACHED_VERSION
|
||||
|
||||
# trap for TMP Cleanup
|
||||
trap "rm -rf '$TMP_DIR'" EXIT
|
||||
|
||||
CACHED_VERSION=$(get_cached_version "uv")
|
||||
|
||||
# Architecture Detection
|
||||
local ARCH=$(uname -m)
|
||||
local OS_TYPE=""
|
||||
|
||||
Reference in New Issue
Block a user