fix(install): show detected distro in sudo apt Accept prompt (#7324)
* fix(install): show detected distro in sudo apt Accept prompt Make the package-install elevation prompt name the detected distro and state that packages come from official apt repos, so users know we are not installing a tarball outside their package manager (#6207). * fix(install): avoid case/;; inside $() for bash 3.2 macOS CI uses bash 3.2, which misparses case arms inside command substitution and fails install.sh at the apt distro helper. Use a plain subshell so the Accept? prompt still works everywhere.
This commit is contained in:
parent
f5a0c2226b
commit
0807d03ed0
2 changed files with 128 additions and 1 deletions
35
install.sh
35
install.sh
|
|
@ -625,6 +625,36 @@ _is_pkg_installed() {
|
|||
esac
|
||||
}
|
||||
|
||||
# ── Helper: human-readable apt distro label for the sudo package prompt (#6207) ──
|
||||
# Reads /etc/os-release so the Accept? prompt can say which distro we detected and
|
||||
# that packages come from that distro's official apt repos (not a tarball).
|
||||
_apt_distro_description() {
|
||||
# Plain ( ... ) subshell — not $() — so case/;; stays bash-3.2-safe on macOS.
|
||||
# Bash 3.2 misparses case arms inside command substitution and errors on `;;`.
|
||||
(
|
||||
if [ ! -r /etc/os-release ]; then
|
||||
printf 'a debian-like system'
|
||||
exit 0
|
||||
fi
|
||||
# shellcheck disable=SC1091
|
||||
. /etc/os-release 2>/dev/null || true
|
||||
if [ -n "${NAME:-}" ] && [ -n "${VERSION_ID:-}" ]; then
|
||||
_ad_label="$NAME $VERSION_ID"
|
||||
elif [ -n "${PRETTY_NAME:-}" ]; then
|
||||
_ad_label="$PRETTY_NAME"
|
||||
elif [ -n "${NAME:-}" ]; then
|
||||
_ad_label="$NAME"
|
||||
else
|
||||
printf 'a debian-like system'
|
||||
exit 0
|
||||
fi
|
||||
case " ${ID:-} ${ID_LIKE:-} " in
|
||||
*" debian "*|*" ubuntu "*) _ad_label="${_ad_label} (debian-like)" ;;
|
||||
esac
|
||||
printf '%s' "$_ad_label"
|
||||
)
|
||||
}
|
||||
|
||||
# ── Helper: install packages via apt, escalating to sudo only if needed ──
|
||||
# Usage: _smart_apt_install pkg1 pkg2 pkg3 ...
|
||||
_smart_apt_install() {
|
||||
|
|
@ -655,11 +685,14 @@ _smart_apt_install() {
|
|||
|
||||
# Step 3: Escalate -- need elevated permissions for remaining packages
|
||||
if command -v sudo >/dev/null 2>&1; then
|
||||
_ad_desc="$(_apt_distro_description)"
|
||||
echo ""
|
||||
echo " !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
echo " WARNING: We require sudo elevated permissions to install:"
|
||||
echo " $_STILL_MISSING"
|
||||
echo " If you accept, we'll run sudo now, and it'll prompt your password."
|
||||
echo " Detected ${_ad_desc}."
|
||||
echo " If you accept, we'll run sudo apt-get to install these packages"
|
||||
echo " from your distro's official repositories (not a third-party tarball)."
|
||||
echo " !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
echo ""
|
||||
printf " Accept? [Y/n] "
|
||||
|
|
|
|||
94
tests/sh/test_apt_distro_prompt.sh
Executable file
94
tests/sh/test_apt_distro_prompt.sh
Executable file
|
|
@ -0,0 +1,94 @@
|
|||
#!/bin/bash
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
# Copyright 2026-present the Unsloth AI Inc. team. All rights reserved. See /studio/LICENSE.AGPL-3.0
|
||||
# Unit tests for install.sh's _apt_distro_description helper (#6207).
|
||||
# The sudo Accept? prompt should name the detected distro and say packages come
|
||||
# from official apt repos. Hermetic: extract the helper and rewrite
|
||||
# /etc/os-release to per-test fixtures (same pattern as test_strixhalo_wsl_reroute.sh).
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
INSTALL_SH="$SCRIPT_DIR/../../install.sh"
|
||||
PASS=0
|
||||
FAIL=0
|
||||
|
||||
_TMP_ROOT=$(mktemp -d)
|
||||
trap 'rm -rf "$_TMP_ROOT"' EXIT
|
||||
|
||||
assert_eq() {
|
||||
_label="$1"; _expected="$2"; _actual="$3"
|
||||
if [ "$_actual" = "$_expected" ]; then
|
||||
echo " PASS: $_label"; PASS=$((PASS + 1))
|
||||
else
|
||||
echo " FAIL: $_label (expected '$_expected', got '$_actual')"; FAIL=$((FAIL + 1))
|
||||
fi
|
||||
}
|
||||
|
||||
assert_contains() {
|
||||
_label="$1"; _hay="$2"; _needle="$3"
|
||||
case "$_hay" in
|
||||
*"$_needle"*) echo " PASS: $_label"; PASS=$((PASS + 1)) ;;
|
||||
*) echo " FAIL: $_label (missing '$_needle' in: $_hay)"; FAIL=$((FAIL + 1)) ;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Extract helper with /etc/os-release rewritten to $1.
|
||||
build_func() {
|
||||
_fix="$1"
|
||||
_f=$(mktemp -p "$_TMP_ROOT")
|
||||
sed -n '/^_apt_distro_description()/,/^}/p' "$INSTALL_SH" \
|
||||
| sed -e "s#/etc/os-release#$_fix/os-release#g" \
|
||||
> "$_f"
|
||||
echo "$_f"
|
||||
}
|
||||
|
||||
run_desc() {
|
||||
_os="$1"
|
||||
_d=$(mktemp -d -p "$_TMP_ROOT")
|
||||
printf '%s\n' "$_os" > "$_d/os-release"
|
||||
_f=$(build_func "$_d")
|
||||
# shellcheck disable=SC1090
|
||||
. "$_f"
|
||||
_apt_distro_description
|
||||
}
|
||||
|
||||
echo "=== _apt_distro_description ==="
|
||||
|
||||
assert_eq "ubuntu name+version debian-like" \
|
||||
"Ubuntu 24.04 (debian-like)" \
|
||||
"$(run_desc "$(printf 'NAME=\"Ubuntu\"\nVERSION_ID=\"24.04\"\nID=ubuntu\nID_LIKE=debian\n')")"
|
||||
|
||||
assert_eq "debian name+version debian-like" \
|
||||
"Debian GNU/Linux 12 (debian-like)" \
|
||||
"$(run_desc "$(printf 'NAME=\"Debian GNU/Linux\"\nVERSION_ID=\"12\"\nID=debian\n')")"
|
||||
|
||||
assert_eq "pretty_name fallback when name/version missing" \
|
||||
"Linux Mint 22 (debian-like)" \
|
||||
"$(run_desc "$(printf 'PRETTY_NAME=\"Linux Mint 22\"\nID=linuxmint\nID_LIKE=\"ubuntu debian\"\n')")"
|
||||
|
||||
# NAME alone (no VERSION_ID) — still prefer NAME over PRETTY_NAME.
|
||||
assert_eq "name only" \
|
||||
"Pop!_OS (debian-like)" \
|
||||
"$(run_desc "$(printf 'NAME=\"Pop!_OS\"\nID=pop\nID_LIKE=\"ubuntu debian\"\n')")"
|
||||
|
||||
assert_eq "missing os-release file" \
|
||||
"a debian-like system" \
|
||||
"$(
|
||||
_d=$(mktemp -d -p "$_TMP_ROOT")
|
||||
_f=$(build_func "$_d")
|
||||
# shellcheck disable=SC1090
|
||||
. "$_f"
|
||||
_apt_distro_description
|
||||
)"
|
||||
|
||||
echo "=== _smart_apt_install prompt contract ==="
|
||||
_smart=$(sed -n '/^_smart_apt_install()/,/^}/p' "$INSTALL_SH")
|
||||
assert_contains "calls distro helper" "$_smart" '_apt_distro_description'
|
||||
assert_contains "names detected distro" "$_smart" 'Detected ${_ad_desc}'
|
||||
assert_contains "mentions apt-get" "$_smart" 'sudo apt-get'
|
||||
assert_contains "mentions official repos" "$_smart" "official repositories"
|
||||
assert_contains "rejects tarball worry" "$_smart" "not a third-party tarball"
|
||||
|
||||
echo ""
|
||||
echo "Results: $PASS passed, $FAIL failed"
|
||||
[ "$FAIL" -eq 0 ]
|
||||
Loading…
Add table
Add a link
Reference in a new issue