Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix cross-drive script installation #11167

Merged
merged 3 commits into from
Feb 12, 2025
Merged

Fix cross-drive script installation #11167

merged 3 commits into from
Feb 12, 2025

Conversation

konstin
Copy link
Member

@konstin konstin commented Feb 2, 2025

Fallback to copy if renaming a script doesn't work, similar to the site packages installation.

Fixes #11163

Test Plan

Failing:

docker volume rm -f gh11163_usr_local_bin
docker run -v gh11163_usr_local_bin:/usr/local/bin -e UV_LINK_MODE=copy -v $(pwd):/io -it --rm ghcr.io/astral-sh/uv:0.5-python3.11-bookworm-slim uv pip install --system ruff

Passing:

cargo build --target x86_64-unknown-linux-musl
docker volume rm -f gh11163_usr_local_bin
docker run -v gh11163_usr_local_bin:/usr/local/bin -e UV_LINK_MODE=copy -v $(pwd):/io -it --rm ghcr.io/astral-sh/uv:0.5-python3.11-bookworm-slim /io/target/x86_64-unknown-linux-musl/debug/uv pip install --system ruff

@konstin konstin added the bug Something isn't working label Feb 2, 2025
Comment on lines 485 to 504
// Here, two wrappers over rename are clashing: We want to retry for security software
// blocking the file, but we also need the copy fallback is the problem was trying to
// move a file cross-drive.
match uv_fs::rename_with_retry_sync(&path, &script_absolute) {
Ok(()) => (),
Err(err) => {
debug!("Failed to rename, falling back to copy: {err}");
fs_err::copy(&path, &script_absolute)?;
}
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:/

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we do copy_with_retry_sync here, in the inner loop?

Also, does rename_with_retry_sync retry if the error is due to different drives? Hopefully not?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have a copy_with_retry_sync?

This is mostly guess work, my idea was the security checkers would make the `rename_with_retry_sync loop fail and then the copy would succeed first try, but we can make this more defensive if we have a good way to.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was suggesting we create it? I think the more important question here though is whether we can catch the "different drive" error, or whether we need this catch-all Err(err) branch. Do you know?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I looked into it myself, and CrossesDevices is unstable. Please add a TODO here to catch that error when it stabilizes. Then decide whether you want to add a copy_with_retry_sync method (I would suggest doing so, but it's up to you) and go ahead with the merge.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah now I get what you were getting at.

I now implemented the more defensive version where we retry in both rename or copy. The callback version is kinda ugly but it's only used in this one place.

I didn't realize there was a dedicated error code for cross drive, i had initially assumed that this is part of some other platform-specific error code. Once it stabilized we can upgrade this code path.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you have suggestions for a prettier version of with_retry_sync i'll follow up.

@konstin konstin force-pushed the konsti/fix-data-move branch from afb681e to 7480131 Compare February 4, 2025 12:10
match self {
Self::Rename => match fs_err::rename(from.as_ref(), to.as_ref()) {
Ok(()) => {}
Err(err) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same question here: can we make this branch exclusive to "different drive"? Is there an error kind for it?

Fallback to copy if renaming a script doesn't work, similar to the site packages installation.

**Test Plan**

```
cargo build --target x86_64-unknown-linux-musl
docker volume rm -f gh11163_usr_local_bin
docker run -v gh11163_usr_local_bin:/usr/local/bin -e UV_LINK_MODE=copy -v $(pwd):/io -it --rm ghcr.io/astral-sh/uv:0.5-python3.11-bookworm-slim /io/target/x86_64-unknown-linux-musl/debug/uv pip install --system ruff
docker volume rm -f gh11163_usr_local_bin
docker run -v gh11163_usr_local_bin:/usr/local/bin -e UV_LINK_MODE=copy -v $(pwd):/io -it --rm ghcr.io/astral-sh/uv:0.5-python3.11-bookworm-slim uv pip install --system ruff
```
@konstin konstin force-pushed the konsti/fix-data-move branch from b564fbd to f5e33ec Compare February 12, 2025 17:52
@konstin konstin merged commit 070120e into main Feb 12, 2025
73 checks passed
@konstin konstin deleted the konsti/fix-data-move branch February 12, 2025 18:00
tmeijn pushed a commit to tmeijn/dotfiles that referenced this pull request Feb 13, 2025
This MR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [astral-sh/uv](https://github.com/astral-sh/uv) | patch | `0.5.30` -> `0.5.31` |

MR created with the help of [el-capitano/tools/renovate-bot](https://gitlab.com/el-capitano/tools/renovate-bot).

**Proposed changes to behavior should be submitted there as MRs.**

---

### Release Notes

<details>
<summary>astral-sh/uv (astral-sh/uv)</summary>

### [`v0.5.31`](https://github.com/astral-sh/uv/blob/HEAD/CHANGELOG.md#0531)

[Compare Source](astral-sh/uv@0.5.30...0.5.31)

##### Enhancements

-   Add `uv sync --script` ([#&#8203;11361](astral-sh/uv#11361))
-   Allow PEP 508 requirements in tool requests ([#&#8203;11337](astral-sh/uv#11337))
-   Allow source distributions to produce wheels with `+local` suffixes ([#&#8203;11429](astral-sh/uv#11429))
-   Bring parity to `uvx` and `uv tool install` requests ([#&#8203;11345](astral-sh/uv#11345))
-   Use a stable directory for local, remote, and stdin script virtual environments ([#&#8203;11347](astral-sh/uv#11347), [#&#8203;11364](astral-sh/uv#11364))
-   Detect infinite recursion in `uv run` ([#&#8203;11386](astral-sh/uv#11386))

##### Python

The managed Python distributions have been updated, including:

-   CPython 3.14.0a5, which includes a new [tail calling interpreter](https://docs.python.org/3.14/whatsnew/3.14.html#whatsnew314-tail-call) for a significant performance improvement
-   The bundled OpenSSL version was updated from 3.0.15 to 3.0.16 which fixes a [security advisory](https://openssl-library.org/news/secadv/20241016.txt)

See the [`python-build-standalone` release notes](https://github.com/astral-sh/python-build-standalone/releases/tag/20250212) for more details.

##### Bug fixes

-   Fix cross-drive script installation ([#&#8203;11167](astral-sh/uv#11167))
-   Add indexes in priority order ([#&#8203;11451](astral-sh/uv#11451))
-   Allow `--python <dir>` requests to match existing environments if `sys.executable` is the same file ([#&#8203;11290](astral-sh/uv#11290))
-   Avoid comparing to system site packages in `--dry-run` mode ([#&#8203;11427](astral-sh/uv#11427))
-   Prefer running executables in the environment with `<name>` over `<name>/__main__.py` ([#&#8203;11431](astral-sh/uv#11431))
-   Retry local clones without hardlinks if they fail ([#&#8203;11421](astral-sh/uv#11421))

##### Documentation

-   Update alternative-indexes.md to use `UV_INDEX` instead of `UV_EXTRA_INDEX_URL` ([#&#8203;11381](astral-sh/uv#11381))
-   Update scripts guide to include using package indexes ([#&#8203;11443](astral-sh/uv#11443))

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever MR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this MR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this MR, check this box

---

This MR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOS4xNjYuMSIsInVwZGF0ZWRJblZlciI6IjM5LjE2Ni4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJSZW5vdmF0ZSBCb3QiXX0=-->
loic-lescoat pushed a commit to loic-lescoat/uv that referenced this pull request Mar 2, 2025
Fallback to copy if renaming a script doesn't work, similar to the site
packages installation.

Fixes astral-sh#11163

**Test Plan**

Failing:
```
docker volume rm -f gh11163_usr_local_bin
docker run -v gh11163_usr_local_bin:/usr/local/bin -e UV_LINK_MODE=copy -v $(pwd):/io -it --rm ghcr.io/astral-sh/uv:0.5-python3.11-bookworm-slim uv pip install --system ruff
```

Passing:
```
cargo build --target x86_64-unknown-linux-musl
docker volume rm -f gh11163_usr_local_bin
docker run -v gh11163_usr_local_bin:/usr/local/bin -e UV_LINK_MODE=copy -v $(pwd):/io -it --rm ghcr.io/astral-sh/uv:0.5-python3.11-bookworm-slim /io/target/x86_64-unknown-linux-musl/debug/uv pip install --system ruff
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

'Invalid cross-device link (os error 18)' during 'ruff' installation in Docker container
2 participants