v0.27.1:0 - fix model download: prepend ~/.local/bin so SSH finds uvx

hf-download.sh shells out to uvx (the uv installer drops it in ~/.local/bin),
but the non-interactive SSH session doesn't source the user's profile, so
~/.local/bin was off PATH and downloads died with "uvx: command not found".
build_download_command now prepends $HOME/.local/bin. Adds test_download.py.
This commit is contained in:
Keysat
2026-06-18 16:44:07 -05:00
parent a20c538ebf
commit 1e1e1cb568
4 changed files with 53 additions and 3 deletions
+15 -1
View File
@@ -23,6 +23,20 @@ from .ssh import ssh_stream, StreamHandle
Mode = Literal["spark1", "spark2", "cluster"]
def build_download_command(repo: str, flags: str = "") -> str:
"""Remote shell command that drives hf-download.sh on a Spark.
Prepends ~/.local/bin to PATH. hf-download.sh shells out to `uvx` (Astral's
uv), and the official uv installer drops its binaries in ~/.local/bin — but
our SSH session is non-interactive, so it never sources the user's profile
and ~/.local/bin is off PATH, leaving `uvx` as "command not found". $HOME
expands server-side, so this stays correct for any adopter/user. `repo` is
shlex-quoted at the sink (validate_repo gates the charset upstream).
"""
serve = f"./hf-download.sh {quote_arg(repo)} {flags}".strip()
return f'export PATH="$HOME/.local/bin:$PATH" && cd ~/spark-vllm-docker && {serve}'
_TQDM_RE = re.compile(
r"(\d+(?:\.\d+)?)\s*%\s*\|.*?\|\s*"
r"([\d.]+[KMG]?B?)\s*/\s*([\d.]+[KMG]?B?)\s*"
@@ -126,7 +140,7 @@ class DownloadManager:
if not target_host or not target_user:
raise RuntimeError(f"{job.mode} host not configured")
cmd = f"cd ~/spark-vllm-docker && ./hf-download.sh {quote_arg(job.repo)} {flags}".strip()
cmd = build_download_command(job.repo, flags)
job.append(f"$ {cmd}")
job.state = "downloading"
job.progress.phase = "Connecting to Hugging Face…"
+35
View File
@@ -0,0 +1,35 @@
"""build_download_command: the ~/.local/bin PATH fix + shell-injection quoting.
hf-download.sh on the Spark shells out to `uvx`, which the uv installer puts in
~/.local/bin — off the PATH of our non-interactive SSH session. The command must
prepend ~/.local/bin (via $HOME, expanded server-side) or the download dies with
"uvx: command not found". The repo value must also be shlex-quoted at the sink so
a crafted value can't break out of the command (validate_repo gates it upstream).
"""
import shlex
from app.download import build_download_command
def test_prepends_local_bin_to_path():
cmd = build_download_command("org/name")
assert cmd.startswith('export PATH="$HOME/.local/bin:$PATH" && ')
assert "cd ~/spark-vllm-docker" in cmd
assert "./hf-download.sh org/name" in cmd
def test_no_trailing_space_without_flags():
assert build_download_command("org/name", "").endswith("./hf-download.sh org/name")
def test_cluster_flags_appended():
cmd = build_download_command("org/name", "-c --copy-parallel")
assert cmd.endswith("./hf-download.sh org/name -c --copy-parallel")
def test_repo_is_shlex_quoted():
# Everything after the script name must shlex-split back to the exact repo,
# the same round-trip invariant build_launch_command relies on.
cmd = build_download_command("org/na;me")
after = cmd.split("./hf-download.sh ", 1)[1]
assert shlex.split(after) == ["org/na;me"]