Skip to content

Commit 3604852

Browse files
committed
ci: fall back to /tmp for the uv install lock when TMPDIR is unwritable
Addresses Claude Code Review on #1630: - flock hard-fails (and skips running uv pip install entirely) if its lock file's directory doesn't exist or isn't writable. TMPDIR can be stale on HPC login nodes (e.g. left over from a prior job's since-deleted scratch dir), so an unconditional flock target risked breaking installs that worked fine before this lock existed. Guard with the same -w check already used for the UV_CACHE_DIR redirect, falling back to /tmp. - Clarified the comment: uv's cache is shared per-user by default (~/.cache/uv), not just in the CI node-local-redirect case, so the serialization also protects concurrent local builds, not only self-hosted CI matrix legs.
1 parent 74db3a0 commit 3604852

1 file changed

Lines changed: 17 additions & 10 deletions

File tree

toolchain/bootstrap/python.sh

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -189,16 +189,23 @@ if ! cmp "$(pwd)/toolchain/pyproject.toml" "$(pwd)/build/pyproject.toml" > /dev/
189189
export UV_CACHE_DIR="${TMPDIR:-/tmp}/uv-cache-${USER:-$(id -un)}"
190190
fi
191191

192-
# Self-hosted HPC runners (Frontier, Phoenix) run several matrix legs
193-
# (interfaces/shards) as the same OS user on the same login node at
194-
# once, all sharing the UV_CACHE_DIR above. uv's own cache lock
195-
# protects individual entries, but concurrent installs can still race
196-
# while uv extracts/prunes the shared archive-v0 store, leaving a
197-
# corrupted entry (e.g. a missing dist-info METADATA file) that fails
198-
# every subsequent install until the cache is manually cleared.
199-
# Serialize the install call itself so only one uv process touches a
200-
# given cache dir at a time.
201-
UV_INSTALL_LOCK="${TMPDIR:-/tmp}/mfc-uv-install-${USER:-$(id -un)}.lock"
192+
# uv's cache (~/.cache/uv by default, or the node-local redirect above
193+
# in CI) is shared per-user across every repo/worktree/matrix leg. uv's
194+
# own cache lock protects individual entries, but concurrent installs
195+
# from separate uv processes can still race while one extracts/prunes
196+
# the shared archive-v0 store, leaving a corrupted entry (e.g. a
197+
# missing dist-info METADATA file) that fails every subsequent install
198+
# until the cache is manually cleared -- both across self-hosted CI
199+
# matrix legs (Frontier, Phoenix) sharing a login node, and across
200+
# concurrent local builds by the same user. Serialize the install
201+
# call itself so only one uv process touches a given cache dir at a
202+
# time. Fall back to /tmp for the lock file itself if TMPDIR isn't
203+
# writable (e.g. a stale TMPDIR left over from a prior job's
204+
# since-deleted scratch dir), so a bad TMPDIR can't break installs
205+
# that used to work fine before this lock existed.
206+
UV_LOCK_DIR="${TMPDIR:-/tmp}"
207+
[ -w "$UV_LOCK_DIR" ] || UV_LOCK_DIR=/tmp
208+
UV_INSTALL_LOCK="${UV_LOCK_DIR}/mfc-uv-install-${USER:-$(id -un)}.lock"
202209
if command -v flock > /dev/null 2>&1; then
203210
uv_install() { flock "$UV_INSTALL_LOCK" uv pip install "$@"; }
204211
else

0 commit comments

Comments
 (0)