fix(uv): colocate the uv Python install dir with the ROCm CLI data dir - #240
fix(uv): colocate the uv Python install dir with the ROCm CLI data dir#240jgmelber wants to merge 1 commit into
Conversation
Follow-on to ROCm#170/ROCm#160: uv_command_env() colocated UV_CACHE_DIR with the managed data dir but left UV_PYTHON_INSTALL_DIR unset, so `uv python install` (invoked by ensure_managed_python) still fell back to uv's own default of $HOME/.local/share/uv/python/, leaking a ~100MB standalone CPython interpreter outside the managed root. Mirrors ROCm#170's UvCacheSource design for the interpreter install dir: UvPythonInstallDirSource with the same managed/override/inherited precedence, a namespaced ROCM_CLI_UV_PYTHON_INSTALL_DIR escape hatch, a one-shot notice for the legacy location, and updated uninstall help text. Also extends the ROCm#175 uninstall reporting: now that the interpreters are the other large thing rocm-cli causes to be downloaded, an overridden install dir outside the data dir is reported as "not removed" rather than silently left behind. Signed-off-by: Joseph Melber <jmelber@amd.com>
|
Reviewed at The uninstall report doesn't honour the override this PR introduces
let uv_python = env_path("UV_PYTHON_INSTALL_DIR").or_else(|| home/.local/share/uv/python);but That contradicts the stated consequence in the description ("uninstall now reports it as a shared cache it is not removing ... rather than silently leaving ~100MB behind"). It holds for the ambient variable and fails for the namespaced one. The new test pins only the ambient path ( Cleanest fix is to stop re-deriving the location in What I checked and found soundThe two variables really are one design applied twice. Keeping The The legacy notice is correctly conservative — gated on the managed dir existing, skipped under an override, one-shot behind a marker file, and it neither moves nor deletes anything. Right call given other uv projects may depend on those interpreters. Non-blocking
Diff review only — I haven't run a real |
Summary
Follow-on to #170. That PR pointed
uvat a cache inside the ROCm CLI data directory; this one does the same for the standalone CPython interpretersuv python installdownloads, which still land in$HOME.Root cause
uv_command_env()now setsUV_CACHE_DIR, but never setUV_PYTHON_INSTALL_DIR.ensure_managed_pythonshells out touv python install, so the interpreter falls back touv's own default —$HOME/.local/share/uv/python/on Linux/macOS,%USERPROFILE%\.local\share\uv\python\on Windows — regardless of whereROCM_CLI_DATA_DIRpoints.That is ~100MB of standalone CPython per interpreter version, outside the managed root. Measured with uv 0.12.3 against a throwaway
HOME:With the variable set to a managed location, the same 104M lands under the data dir and
$HOMEkeeps only uv's 12KBbin/python3.12shim — a symlink into the managed interpreter, not a copy.This is the same class of bug as #160 and it bites the same users: a split
/home, a container overlay, or anyone who setROCM_CLI_DATA_DIRto a larger disk and expects the CLI to stay there.rocm uninstallalso could not reclaim it, since it only removes directories it knows about.Technical decisions
Keyed off
data_dir, for the same reason as the cache:uvhardlinks interpreters into the environments it creates, andROCM_CLI_CACHE_DIRcan point at a different filesystem from those environments.Mirrors
UvCacheSourceexactly.UvPythonInstallDirSourcehas the sameManaged/Override/Inheritedvariants, the samepath()/is_override()surface, and the same precedence: namespacedROCM_CLI_UV_PYTHON_INSTALL_DIR> ambientUV_PYTHON_INSTALL_DIR> managed default. It reusesmeaningful_cache_dirfor trimming rather than duplicating it. The two variables should read as one design applied twice, not two designs.uv_command_env(&AppPaths)keeps its signature. Both env vars are composed inside it, sotherock.rs,comfyui.rs, and the vLLM engine pick up the fix with no call-site edits. This matters for correctness beyond tidiness:ensure_managed_pythoncallsuv python installanduv python findthrough the same helper, sofindcannot disagree with whereinstallput the interpreter.A one-shot notice, not a migration, following
maybe_notice_legacy_uv_cachewith its own marker file. Nothing is moved or deleted — the legacy directory may hold interpreters otheruvprojects depend on.Non-goal:
--prefixinstalls — #187Same gap as the cache, same reason.
--prefixrelocatesinstall_rootonly; the interpreters stay keyed offdata_dir. Documented indocs/manual-testing.mdand pinned byuv_python_install_dir_does_not_follow_a_prefix_install_root, mirroring the existing cache test.Consequences worth noting
rocm uninstallnow reclaims the interpreters too, since they sit under the data directory.--keep-data/--keep-cachehelp text updated to say so;--keep-cachedoes not cover them.uvprojects.ROCM_CLI_UV_PYTHON_INSTALL_DIRrestores that.Tests
Six new resolution tests mirroring the cache suite — unset, empty, whitespace-only, trimmed, inherited, namespaced-override, and precedence between the two — driving the pure resolver, so they need no
set_varand stay parallel-safe.managed_python_install_dir_tracks_rocm_cli_data_dirgoes throughAppPaths::with_managed_root.The uninstall-reporting test is the exception: it drives the real
shared_cache_candidates()behind the existing env lock, because a version calling the pure helper with hand-built inputs still passed when the production block was deleted. Each new test was mutation-checked — production code removed, test confirmed failing, code restored.cargo fmt --all --checkandcargo clippy --locked --workspace --all-targets -- -D warningsare clean. Full workspace suite passes.Manual verification
uv python install 3.12under a throwawayHOMEwith both variables set: the 104M interpreter lands under the managed data dir, and$HOMEreceives only the 12KB shim symlink.