fix(install): address Codex round-2 review (WSL1 distros, build-failure restore, libcurl, shim quoting, opt-out forwarding)

- install.ps1: detect a PRE-EXISTING WSL1 distro up-front (kernel string +
  libcuda probe inside the distro; encoding-proof vs UTF-16 `wsl -l -v`) and
  convert it with `wsl --set-version 2`, failing early with instructions if
  conversion does not take -- instead of completing a full install that only
  fails at the final torch.cuda check (no GPU passthrough under WSL1).
- install.ps1: quote the distro name in the generated unsloth.cmd shim and in
  the copy-pasteable hint commands so UNSLOTH_WSL_DISTRO values with spaces
  ("Ubuntu Preview") keep working.
- install.ps1: forward UNSLOTH_NO_LLAMA_CUDA=1 into the WSL install env; the
  inner setup.sh otherwise defers its llama.cpp build to a background builder
  this script then never dispatches (the same opt-out skips it), leaving no
  llama-server and a misleading "building in background" footer. Also add
  libcurl4-openssl-dev to the WSL bootstrap apt line.
- provision_llama_cuda.sh: install libcurl4-openssl-dev with the base tools --
  _cmake_configure forces -DLLAMA_CURL=ON and on the deferred WSL path this
  script is the only build path (setup.sh's GGUF dep install was skipped), so
  configure failed on fresh hosts without the headers.
- provision_llama_cuda.sh: keep the pre-existing llama.cpp backup until the
  fresh build is CONFIRMED (was: dropped right after a successful clone), and
  restore it on configure/build failure or when no server binary was produced
  -- a failed CUDA build no longer destroys a previously working (CPU) server.
- setup.sh: when provisioning fails and NO llama-server is present, set
  _LLAMA_CPP_DEGRADED=true so the arm64 CPU-prebuilt last resort and the
  installer failure exit fire instead of reporting a working install.

Round-2 comments verified already fixed in ad77ae6 (anchored to its parent
d161ff5): the torch probe already passes --reinstall; the WSL uninstall is
already scoped to /root only.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Daniel Han 2026-06-09 20:07:32 -07:00
commit 8e51d18a6c
3 changed files with 68 additions and 19 deletions

View file

@ -49,8 +49,11 @@ HAVE_APT=0; command -v apt-get >/dev/null 2>&1 && HAVE_APT=1
# without the basic build tools needed to clone/configure llama.cpp.
if [ "$HAVE_APT" -eq 1 ]; then
$SUDO apt-get update -y >/dev/null 2>&1 || true
# libcurl4-openssl-dev: _cmake_configure forces -DLLAMA_CURL=ON, and on the WSL
# deferred path this script is the only build path -- setup.sh's GGUF dep install
# (which covers libcurl) was skipped, so configure would fail without the headers.
$SUDO apt-get install -y --no-install-recommends \
build-essential cmake git curl ca-certificates >/dev/null 2>&1 || true
build-essential cmake git curl ca-certificates libcurl4-openssl-dev >/dev/null 2>&1 || true
$SUDO apt-get install -y --no-install-recommends gcc-14 g++-14 >/dev/null 2>&1 || true
fi
@ -112,11 +115,17 @@ if [ -n "$CC_CAP" ]; then CUDA_ARCH="$CC_CAP"; else CUDA_ARCH="native"; fi
# the user's request instead of always tracking ggml-org main.
mkdir -p "$(dirname "$LLAMA_DIR")"
_LLAMA_REF="${UNSLOTH_LLAMA_TAG:-}"
# Preserve any existing (e.g. CPU-only) llama.cpp so a failed clone OR a failed CUDA
# build doesn't leave the user with NO server: the backup is restored on any failure
# exit and only dropped once a server from the fresh build is confirmed.
_LLAMA_BAK=""
_restore_prev() {
if [ -n "$_LLAMA_BAK" ] && [ -e "$_LLAMA_BAK" ]; then
rm -rf "$LLAMA_DIR" 2>/dev/null
mv "$_LLAMA_BAK" "$LLAMA_DIR" 2>/dev/null && log "restored previous llama.cpp install"
fi
}
if [ ! -d "$LLAMA_DIR/.git" ]; then
# Preserve any existing (e.g. CPU-only) llama.cpp so a FAILED clone doesn't leave the user
# with NO server -- restore it on clone failure. A successful clone makes it obsolete (the
# fresh CUDA build replaces it), so the backup is dropped then.
_LLAMA_BAK=""
if [ -e "$LLAMA_DIR" ]; then
_LLAMA_BAK="${LLAMA_DIR}.prev.$$"
rm -rf "$_LLAMA_BAK" 2>/dev/null
@ -131,12 +140,11 @@ if [ ! -d "$LLAMA_DIR/.git" ]; then
fi
if [ "$_clone_ok" -ne 1 ]; then
log "git clone failed"
[ -n "$_LLAMA_BAK" ] && mv "$_LLAMA_BAK" "$LLAMA_DIR" 2>/dev/null # restore previous server
_restore_prev
exit 0
fi
[ -n "$_LLAMA_BAK" ] && rm -rf "$_LLAMA_BAK" 2>/dev/null
fi
cd "$LLAMA_DIR" || exit 0
cd "$LLAMA_DIR" || { _restore_prev; exit 0; }
log "building CUDA llama.cpp (arch=$CUDA_ARCH, host=$HCXX) - this takes a few minutes..."
_cmake_configure() {
@ -153,7 +161,7 @@ _cmake_configure() {
if ! _cmake_configure; then
log "stale/incompatible CMake cache detected; wiping build dir for a clean CUDA configure"
rm -rf build
_cmake_configure || { log "cmake configure failed"; exit 0; }
_cmake_configure || { log "cmake configure failed"; cd /; _restore_prev; exit 0; }
fi
# Build the full target set unsloth-zoo's GGUF exporter also needs (llama-mtmd-cli,
# llama-gguf-split) so one build serves both Studio inference and save_pretrained_gguf.
@ -192,13 +200,19 @@ if ! _cmake_build; then
# Wipe build/ and rebuild clean once before giving up.
log "build failed (likely interrupted/partial); wiping build dir and rebuilding clean"
rm -rf build
_cmake_configure || { log "cmake configure failed"; exit 0; }
_cmake_build || { log "cmake build failed"; exit 0; }
_cmake_configure || { log "cmake configure failed"; cd /; _restore_prev; exit 0; }
_cmake_build || { log "cmake build failed"; cd /; _restore_prev; exit 0; }
fi
if is_cuda_server "$SERVER"; then
log "CUDA llama-server ready: $SERVER"
else
[ -n "$_LLAMA_BAK" ] && rm -rf "$_LLAMA_BAK" 2>/dev/null
elif [ -x "$SERVER" ]; then
# A server exists but isn't CUDA-confirmed; still better than the old backup.
log "build finished but CUDA llama-server could not be confirmed"
[ -n "$_LLAMA_BAK" ] && rm -rf "$_LLAMA_BAK" 2>/dev/null
else
log "build finished but no llama-server was produced"
cd /; _restore_prev
fi
exit 0