tools.func: fix mongodb version comparison, guard apt purge against removing dependents (#16795)

This commit is contained in:
CanbiZ (MickLesk)
2026-08-26 21:24:33 +02:00
committed by GitHub
parent 408e74da4a
commit 416deb8fd0
+67 -7
View File
@@ -632,7 +632,7 @@ is_tool_installed() {
;;
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)
installed_version=$(mongod --version 2>/dev/null | awk '/db version/{print $3}' | sed 's/^v//' | cut -d. -f1,2)
fi
;;
node | nodejs)
@@ -685,6 +685,39 @@ is_tool_installed() {
return 0 # Installed and version matches (if specified)
}
# ------------------------------------------------------------------------------
# Checks whether purging the given package glob(s) would also remove packages
# outside those globs (i.e. reverse dependents, such as an app depending on
# mongodb-org-server). Uses `apt-get -s` (simulate) with the stable apt-get
# output format, not `apt`, whose output is explicitly unstable for scripting.
# Returns 0 (safe to purge) or 1 (unsafe - prints the unexpected packages).
# Usage: _purge_is_safe 'mongodb*' ['other-glob*' ...]
# ------------------------------------------------------------------------------
_purge_is_safe() {
local -a globs=("$@")
local -a collateral=()
local pkg glob matched
local sim_out
sim_out=$(apt-get -s purge -y "${globs[@]}" 2>/dev/null) || return 0
while IFS= read -r pkg; do
[[ -z "$pkg" ]] && continue
matched=0
for glob in "${globs[@]}"; do
# shellcheck disable=SC2053
[[ "$pkg" == $glob ]] && {
matched=1
break
}
done
((matched)) || collateral+=("$pkg")
done < <(awk '/^(Remv|Purg) /{print $2}' <<<"$sim_out")
if ((${#collateral[@]} > 0)); then
msg_warn "Refusing purge of '${globs[*]}': would also remove ${collateral[*]}"
return 1
fi
return 0
}
# ------------------------------------------------------------------------------
# Remove old tool version completely (purge + cleanup repos)
# Usage: remove_old_tool_version "mariadb" "repository-name"
@@ -696,11 +729,13 @@ remove_old_tool_version() {
case "$tool_name" in
mariadb)
stop_all_services "mariadb"
_purge_is_safe 'mariadb*' || return 1
$STD apt purge -y 'mariadb*' >/dev/null 2>&1 || true
cleanup_tool_keyrings "mariadb"
;;
mysql)
stop_all_services "mysql"
_purge_is_safe 'mysql*' || return 1
$STD apt purge -y 'mysql*' >/dev/null 2>&1 || true
# Keep data directory for safety (remove manually if needed)
# rm -rf /var/lib/mysql 2>/dev/null || true
@@ -708,12 +743,14 @@ remove_old_tool_version() {
;;
mongodb)
stop_all_services "mongod"
_purge_is_safe 'mongodb*' || return 1
$STD apt purge -y 'mongodb*' >/dev/null 2>&1 || 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)
_purge_is_safe nodejs npm || return 1
$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
@@ -726,23 +763,27 @@ remove_old_tool_version() {
;;
php)
stop_all_services "php.*-fpm"
_purge_is_safe 'php*' || return 1
$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"
_purge_is_safe 'postgresql*' || return 1
$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)
_purge_is_safe 'temurin*' 'adoptium*' 'openjdk*' || return 1
$STD apt purge -y 'temurin*' 'adoptium*' 'openjdk*' >/dev/null 2>&1 || true
cleanup_tool_keyrings "adoptium"
;;
ruby)
cleanup_legacy_install "ruby"
_purge_is_safe 'ruby*' || return 1
$STD apt purge -y 'ruby*' >/dev/null 2>&1 || true
;;
rust)
@@ -754,6 +795,7 @@ remove_old_tool_version() {
;;
clickhouse)
stop_all_services "clickhouse-server"
_purge_is_safe 'clickhouse*' || return 1
$STD apt purge -y 'clickhouse*' >/dev/null 2>&1 || true
# Keep data directory for safety (remove manually if needed)
# rm -rf /var/lib/clickhouse 2>/dev/null || true
@@ -4473,7 +4515,10 @@ setup_clickhouse() {
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"
remove_old_tool_version "clickhouse" || {
msg_error "Aborting ClickHouse upgrade: another package depends on it"
return 1
}
else
msg_info "Setup ClickHouse $CLICKHOUSE_VERSION"
fi
@@ -5150,7 +5195,10 @@ setup_go() {
# 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"
remove_old_tool_version "go" || {
msg_error "Aborting Go upgrade: another package depends on it"
return 1
}
else
msg_info "Setup Go $GO_VERSION"
fi
@@ -6753,7 +6801,10 @@ EOF
# Scenario 2b: Different version installed - clean upgrade
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"
remove_old_tool_version "mariadb" || {
msg_error "Aborting MariaDB upgrade: another package depends on it"
return 1
}
fi
# Scenario 3: Fresh install or version change with specific version
@@ -7283,7 +7334,10 @@ setup_mongodb() {
# 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"
remove_old_tool_version "mongodb" || {
msg_error "Aborting MongoDB upgrade: another package depends on it (e.g. an app using it)"
return 1
}
else
msg_info "Setup MongoDB $MONGO_VERSION"
fi
@@ -7473,7 +7527,10 @@ setup_mysql() {
# Scenario 2: Different version installed - clean upgrade
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"
remove_old_tool_version "mysql" || {
msg_error "Aborting MySQL upgrade: another package depends on it"
return 1
}
else
msg_info "Setup MySQL $MYSQL_VERSION"
fi
@@ -7637,7 +7694,10 @@ setup_nodejs() {
if [[ -n "$CURRENT_NODE_VERSION" && "$CURRENT_NODE_VERSION" != "$NODE_VERSION" ]]; then
msg_info "Upgrade Node.js from $CURRENT_NODE_VERSION to $NODE_VERSION"
node_setup_ok_msg="Upgrade Node.js to $NODE_VERSION"
remove_old_tool_version "nodejs"
remove_old_tool_version "nodejs" || {
msg_error "Aborting Node.js upgrade: another package depends on it"
return 1
}
else
msg_info "Setup Node.js $NODE_VERSION"
node_setup_ok_msg="Setup Node.js $NODE_VERSION"