Skip to content

Commit 7cea42d

Browse files
committed
system.func: fix mongodb version comparison, guard apt purge against removing dependents
1 parent 14d94a8 commit 7cea42d

3 files changed

Lines changed: 67 additions & 7 deletions

File tree

lib/db.func

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,10 @@ setup_clickhouse() {
6565
if [[ -n "$CURRENT_VERSION" && "$CURRENT_VERSION" != "$CLICKHOUSE_VERSION" ]]; then
6666
msg_info "Upgrade ClickHouse from $CURRENT_VERSION to $CLICKHOUSE_VERSION"
6767
stop_all_services "clickhouse-server"
68-
remove_old_tool_version "clickhouse"
68+
remove_old_tool_version "clickhouse" || {
69+
msg_error "Aborting ClickHouse upgrade: another package depends on it"
70+
return 1
71+
}
6972
else
7073
msg_info "Setup ClickHouse $CLICKHOUSE_VERSION"
7174
fi
@@ -288,7 +291,10 @@ EOF
288291
# Scenario 2b: Different version installed - clean upgrade
289292
if [[ -n "$CURRENT_VERSION" ]] && ! version_matches_spec "$CURRENT_VERSION" "$MARIADB_VERSION"; then
290293
msg_info "Upgrade MariaDB from $CURRENT_VERSION to $MARIADB_VERSION"
291-
remove_old_tool_version "mariadb"
294+
remove_old_tool_version "mariadb" || {
295+
msg_error "Aborting MariaDB upgrade: another package depends on it"
296+
return 1
297+
}
292298
fi
293299

294300
# Scenario 3: Fresh install or version change with specific version
@@ -818,7 +824,10 @@ setup_mongodb() {
818824
# Scenario 2: Different version installed - clean upgrade
819825
if [[ -n "$INSTALLED_VERSION" && "$INSTALLED_VERSION" != "$MONGO_VERSION" ]]; then
820826
msg_info "Upgrade MongoDB from $INSTALLED_VERSION to $MONGO_VERSION"
821-
remove_old_tool_version "mongodb"
827+
remove_old_tool_version "mongodb" || {
828+
msg_error "Aborting MongoDB upgrade: another package depends on it (e.g. an app using it)"
829+
return 1
830+
}
822831
else
823832
msg_info "Setup MongoDB $MONGO_VERSION"
824833
fi
@@ -1008,7 +1017,10 @@ setup_mysql() {
10081017
# Scenario 2: Different version installed - clean upgrade
10091018
if [[ -n "$CURRENT_VERSION" ]] && ! version_matches_spec "$CURRENT_VERSION" "$MYSQL_VERSION"; then
10101019
msg_info "Upgrade MySQL from $CURRENT_VERSION to $MYSQL_VERSION"
1011-
remove_old_tool_version "mysql"
1020+
remove_old_tool_version "mysql" || {
1021+
msg_error "Aborting MySQL upgrade: another package depends on it"
1022+
return 1
1023+
}
10121024
else
10131025
msg_info "Setup MySQL $MYSQL_VERSION"
10141026
fi

lib/runtime.func

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -875,7 +875,10 @@ setup_go() {
875875
# Scenario 2: Different version or not installed
876876
if [[ -n "$CURRENT_VERSION" && "$CURRENT_VERSION" != "$GO_VERSION" ]]; then
877877
msg_info "Upgrade Go from $CURRENT_VERSION to $GO_VERSION"
878-
remove_old_tool_version "go"
878+
remove_old_tool_version "go" || {
879+
msg_error "Aborting Go upgrade: another package depends on it"
880+
return 1
881+
}
879882
else
880883
msg_info "Setup Go $GO_VERSION"
881884
fi
@@ -1253,7 +1256,10 @@ setup_nodejs() {
12531256
if [[ -n "$CURRENT_NODE_VERSION" && "$CURRENT_NODE_VERSION" != "$NODE_VERSION" ]]; then
12541257
msg_info "Upgrade Node.js from $CURRENT_NODE_VERSION to $NODE_VERSION"
12551258
node_setup_ok_msg="Upgrade Node.js to $NODE_VERSION"
1256-
remove_old_tool_version "nodejs"
1259+
remove_old_tool_version "nodejs" || {
1260+
msg_error "Aborting Node.js upgrade: another package depends on it"
1261+
return 1
1262+
}
12571263
else
12581264
msg_info "Setup Node.js $NODE_VERSION"
12591265
node_setup_ok_msg="Setup Node.js $NODE_VERSION"

lib/system.func

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -605,7 +605,7 @@ is_tool_installed() {
605605
;;
606606
mongodb | mongod)
607607
if command -v mongod >/dev/null 2>&1; then
608-
installed_version=$(mongod --version 2>/dev/null | awk '/db version/{print $3}' | cut -d. -f1,2)
608+
installed_version=$(mongod --version 2>/dev/null | awk '/db version/{print $3}' | sed 's/^v//' | cut -d. -f1,2)
609609
fi
610610
;;
611611
node | nodejs)
@@ -658,6 +658,39 @@ is_tool_installed() {
658658
return 0 # Installed and version matches (if specified)
659659
}
660660

661+
# ------------------------------------------------------------------------------
662+
# Checks whether purging the given package glob(s) would also remove packages
663+
# outside those globs (i.e. reverse dependents, such as an app depending on
664+
# mongodb-org-server). Uses `apt-get -s` (simulate) with the stable apt-get
665+
# output format, not `apt`, whose output is explicitly unstable for scripting.
666+
# Returns 0 (safe to purge) or 1 (unsafe - prints the unexpected packages).
667+
# Usage: _purge_is_safe 'mongodb*' ['other-glob*' ...]
668+
# ------------------------------------------------------------------------------
669+
_purge_is_safe() {
670+
local -a globs=("$@")
671+
local -a collateral=()
672+
local pkg glob matched
673+
local sim_out
674+
sim_out=$(apt-get -s purge -y "${globs[@]}" 2>/dev/null) || return 0
675+
while IFS= read -r pkg; do
676+
[[ -z "$pkg" ]] && continue
677+
matched=0
678+
for glob in "${globs[@]}"; do
679+
# shellcheck disable=SC2053
680+
[[ "$pkg" == $glob ]] && {
681+
matched=1
682+
break
683+
}
684+
done
685+
((matched)) || collateral+=("$pkg")
686+
done < <(awk '/^(Remv|Purg) /{print $2}' <<<"$sim_out")
687+
if ((${#collateral[@]} > 0)); then
688+
msg_warn "Refusing purge of '${globs[*]}': would also remove ${collateral[*]}"
689+
return 1
690+
fi
691+
return 0
692+
}
693+
661694
# ------------------------------------------------------------------------------
662695
# Remove old tool version completely (purge + cleanup repos)
663696
# Usage: remove_old_tool_version "mariadb" "repository-name"
@@ -669,24 +702,28 @@ remove_old_tool_version() {
669702
case "$tool_name" in
670703
mariadb)
671704
stop_all_services "mariadb"
705+
_purge_is_safe 'mariadb*' || return 1
672706
$STD apt purge -y 'mariadb*' >/dev/null 2>&1 || true
673707
cleanup_tool_keyrings "mariadb"
674708
;;
675709
mysql)
676710
stop_all_services "mysql"
711+
_purge_is_safe 'mysql*' || return 1
677712
$STD apt purge -y 'mysql*' >/dev/null 2>&1 || true
678713
# Keep data directory for safety (remove manually if needed)
679714
# rm -rf /var/lib/mysql 2>/dev/null || true
680715
cleanup_tool_keyrings "mysql"
681716
;;
682717
mongodb)
683718
stop_all_services "mongod"
719+
_purge_is_safe 'mongodb*' || return 1
684720
$STD apt purge -y 'mongodb*' >/dev/null 2>&1 || true
685721
# Keep data directory for safety (remove manually if needed)
686722
# rm -rf /var/lib/mongodb 2>/dev/null || true
687723
cleanup_tool_keyrings "mongodb"
688724
;;
689725
node | nodejs)
726+
_purge_is_safe nodejs npm || return 1
690727
$STD apt purge -y nodejs npm >/dev/null 2>&1 || true
691728
# Clean up npm global modules
692729
if command -v npm >/dev/null 2>&1; then
@@ -699,23 +736,27 @@ remove_old_tool_version() {
699736
;;
700737
php)
701738
stop_all_services "php.*-fpm"
739+
_purge_is_safe 'php*' || return 1
702740
$STD apt purge -y 'php*' >/dev/null 2>&1 || true
703741
rm -rf /etc/php 2>/dev/null || true
704742
cleanup_tool_keyrings "deb.sury.org-php" "php"
705743
;;
706744
postgresql)
707745
stop_all_services "postgresql"
746+
_purge_is_safe 'postgresql*' || return 1
708747
$STD apt purge -y 'postgresql*' >/dev/null 2>&1 || true
709748
# Keep data directory for safety (can be removed manually if needed)
710749
# rm -rf /var/lib/postgresql 2>/dev/null || true
711750
cleanup_tool_keyrings "postgresql" "pgdg"
712751
;;
713752
java)
753+
_purge_is_safe 'temurin*' 'adoptium*' 'openjdk*' || return 1
714754
$STD apt purge -y 'temurin*' 'adoptium*' 'openjdk*' >/dev/null 2>&1 || true
715755
cleanup_tool_keyrings "adoptium"
716756
;;
717757
ruby)
718758
cleanup_legacy_install "ruby"
759+
_purge_is_safe 'ruby*' || return 1
719760
$STD apt purge -y 'ruby*' >/dev/null 2>&1 || true
720761
;;
721762
rust)
@@ -727,6 +768,7 @@ remove_old_tool_version() {
727768
;;
728769
clickhouse)
729770
stop_all_services "clickhouse-server"
771+
_purge_is_safe 'clickhouse*' || return 1
730772
$STD apt purge -y 'clickhouse*' >/dev/null 2>&1 || true
731773
# Keep data directory for safety (remove manually if needed)
732774
# rm -rf /var/lib/clickhouse 2>/dev/null || true

0 commit comments

Comments
 (0)