From dc24bba43e9524b31ee216583c01dfaee2ee93bd Mon Sep 17 00:00:00 2001 From: Daniel Han Date: Sun, 26 Jul 2026 05:22:28 -0700 Subject: [PATCH] install.sh, setup.sh: apply the no-tty consent fix to the remaining sites (#7470) Follow-up to #7435, which fixed _smart_apt_install. Three sites were left. studio/setup.sh: the WSL GGUF build-deps block is the pre-#7435 install.sh pattern verbatim. It probes with 'test -r /dev/tty', assumes REPLY=y when that fails, and then runs the elevated apt-get with stdin open. Its own guard comment says a password is needed on WSL, so this is exactly the scenario from issue #7307, and install.sh runs setup.sh in the same install. Give it the same treatment: a real open probe, -n -k with stdin closed on the headless path, and the manual command plus the existing _SKIP_GGUF_BUILD degradation on failure. The helper is defined locally because setup.sh runs as its own process. install.sh autostart prompt: still used 'test -r /dev/tty' and printed the question before checking, leaving a dangling prompt in container logs. Reuse _can_read_tty and move the printf inside the branch. install.sh interactive escalation: a sudoers denial, a wrong password or an apt error aborted on the bare message while the headless branch printed what to run by hand. Make both symmetric. Co-authored-by: danielhanchen --- install.sh | 22 ++++++++-- studio/setup.sh | 64 ++++++++++++++++++++++-------- tests/sh/test_apt_distro_prompt.sh | 12 ++++++ 3 files changed, 77 insertions(+), 21 deletions(-) diff --git a/install.sh b/install.sh index f7d4baa19c..d90195399d 100755 --- a/install.sh +++ b/install.sh @@ -718,8 +718,20 @@ _smart_apt_install() { exit 1 ;; esac - sudo apt-get update -y /dev/null 2>&1 +} + _is_verbose() { [ "${UNSLOTH_VERBOSE:-0}" = "1" ] } @@ -1510,25 +1519,46 @@ if [ "$_NEED_LLAMA_SOURCE_BUILD" = true ] && grep -qi microsoft /proc/version 2> step "gguf deps" "installed" elif command -v sudo >/dev/null 2>&1; then step "gguf deps" "sudo required for: $_STILL_MISSING" "$C_WARN" - printf " %-15s" "" - printf "accept? [Y/n] " - if [ -r /dev/tty ]; then - read -r REPLY &2 + return 1 + fi echo "SUDO_RAN: $*" } # shellcheck disable=SC1090 @@ -199,6 +204,13 @@ _out=$(run_smart tty needspasswd) assert_contains "tty present: still prompts" "$_out" "Accept? [Y/n]" assert_contains "tty present: accepts and installs" "$_out" "SUDO_RAN: apt-get install -y cmake" +# Consent given at a real tty, but the elevated apt-get fails anyway (sudoers +# denial, wrong password, apt error). The interactive branch must say what to +# run by hand, like the headless branch does, not die on the bare sudo error. +_out=$(run_smart tty denied) +assert_contains "tty + denied sudo: gives the manual command" \ + "$_out" "sudo apt-get update -y && sudo apt-get install -y cmake" + # No sudo at all keeps its own message. _out=$(run_smart notty absent) assert_contains "no sudo binary: unchanged message" "$_out" "sudo is not available on this system"