Skip to content

[ci] Switch to the CI-infra-hosted PyPI index proxy - #65687

Open
thomasdesr wants to merge 2 commits into
ray-project:masterfrom
thomasdesr:pypi-hosted-index
Open

[ci] Switch to the CI-infra-hosted PyPI index proxy#65687
thomasdesr wants to merge 2 commits into
ray-project:masterfrom
thomasdesr:pypi-hosted-index

Conversation

@thomasdesr

Copy link
Copy Markdown
Contributor

CI infra runs the PyPI index proxy on the mirror fleet now, so this repo no longer needs to start its own copy in every job. Switching to the hosted endpoint deletes the local proxy and everything that existed to reach it:

  • ci/pypi_index_proxy.py, ci/install_pypi_proxy.sh, and the per-image interpreter/venv installs are deleted. ci/pypi_proxy_profile.sh stays as the single decision file: probe the hosted index once per step, export the index variables on success, export nothing on failure and the step resolves from public PyPI as before.
  • The trusted-host machinery is deleted end to end (.bazelrc and container.py passthroughs, build-arg forwarding in linux_container.py and byod/build.py, ARG/ENV in eight Dockerfiles, build_args in twelve wanda specs). It existed because the local proxy's addresses were non-loopback plain HTTP, which pip refuses without a named trusted host; the hosted endpoint is HTTPS.
  • PIP_EXTRA_INDEX_URL/UV_EXTRA_INDEX_URL forwarding is deleted (nothing ever set them; the real extra indexes live inside the deplock files), as is BYOD's --add-host rayci.localhost (nothing resolves that name).
  • The images stop baking ENV PIP_INDEX_URL/UV_INDEX_URL; the value arrives as ARG, which covers the build and does not persist: BYOD images run outside CI, where a baked CI index can never resolve.

🤖 Generated with Claude Code

thomasdesr and others added 2 commits August 23, 2026 17:25
The mirror fleet now hosts the index proxy itself, at
<mirror>/_pypi/simple: index pages come back with every
files.pythonhosted.org URL rewritten to the mirror, over HTTPS on a
public CA. That removes the reason the job-local proxy existed, so this
deletes it and its whole support structure:

- ci/pypi_proxy_profile.sh probes the hosted index and exports one URL
  for every consumer: pip/uv on the agent, docker builds
  (RAYCI_IMAGE_PIP_INDEX_URL, no --add-host and no trusted-host since
  the address is neither loopback nor plain HTTP), and nested
  containers. No local process, port, venv, or interpreter hunt.
- ci/pypi_proxy_agent.sh and ci/ray_ci/macos/pypi_proxy.sh become thin
  shims sourcing the shared profile script.
- ci/pypi_index_proxy.py and ci/install_pypi_proxy.sh are deleted; the
  forge and manylinux layers now install only the profile.d hook and
  the bazel downloader helper (in /etc/rayci), and forge drops the 3.12
  interpreter that existed only for the proxy venv.

Fail-open semantics are unchanged: the probe decides per step, and an
agent that cannot reach the hosted index resolves from public PyPI with
nothing exported. The bazel downloader rewrite is also unchanged; it
needs only the mirror, and the index probe implies mirror reachability.

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Thomas Desrosiers <thomas@anyscale.com>
…dex does not

Everything here forwarded values that nothing sets since the switch to
the mirror-hosted HTTPS index; each leg existed for the old proxy's
non-loopback plain-HTTP addresses:

- The trusted-host graph: PIP_TRUSTED_HOST/UV_INSECURE_HOST passthrough
  in .bazelrc and ci/ray_ci/container.py, the read-and-forward blocks in
  linux_container.py and byod/build.py, ARG/ENV in eight Dockerfiles,
  RAYCI_IMAGE_PIP_TRUSTED_HOST in twelve wanda specs, and the tests
  pinning those lists. The hosted index is HTTPS on a public CA.
- PIP_EXTRA_INDEX_URL/UV_EXTRA_INDEX_URL forwarding: never set by
  anything; the real extra indexes live inside the deplock files.
- byod/build.py's --add-host rayci.localhost: nothing resolves that name
  any more.
- The baked ENV PIP_INDEX_URL/UV_INDEX_URL becomes ARG-only in the same
  eight Dockerfiles: ARG is visible to every RUN in the stage, which is
  all the bake ever bought, and not persisting it means images no longer
  carry a CI-only index into runtime -- byod images run on Anyscale
  clusters outside the CI VPCs, where the baked value could never
  resolve. That also deletes the profile's reset branch, which existed
  only to neutralize the bake.
- The one-writer cleanups: linux_container.py and byod/build.py read
  only RAYCI_IMAGE_PIP_INDEX_URL, and bazel_mirror_downloader.sh takes
  its mirror argument without a dead default chain.

Kept, each with a live consumer: the per-step probe and fail-open, the
RAYCI_PYPI_MIRROR_URL override (hostname migrations happen), and
RAYCI_IMAGE_PIP_INDEX_URL (docker builds inherit nothing from the step
environment).

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Thomas Desrosiers <thomas@anyscale.com>
@thomasdesr
thomasdesr marked this pull request as ready for review August 24, 2026 00:42
@thomasdesr
thomasdesr requested review from a team as code owners August 24, 2026 00:42

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request simplifies the Ray CI PyPI caching mirror integration by replacing the local rewriting proxy with a centralized, mirror-hosted index. This change eliminates the need for a local proxy process, its installer, and complex trusted-host configurations across various environments (Buildkite agents, macOS, and Docker containers). Feedback on the changes suggests improving the robustness of the diagnostic host resolution in ci/pypi_proxy_profile.sh by dynamically stripping any protocol prefix (e.g., http:// or https://) rather than hardcoding https://.

Comment thread ci/pypi_proxy_profile.sh
# mirror is deployed and this fleet has no route to it". getent is Linux-only;
# on macOS the address line is simply absent.
local resolved
resolved="$(getent hosts "${mirror#https://}" 2>/dev/null | awk '{print $1}' | paste -sd, -)"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

To make the diagnostic host resolution more robust and support mirrors configured with http:// (e.g., in local development or test environments), we should strip any protocol prefix using ${mirror#*://} instead of hardcoding ${mirror#https://}. This is also consistent with how the host is extracted in ci/bazel_mirror_downloader.sh.

Suggested change
resolved="$(getent hosts "${mirror#https://}" 2>/dev/null | awk '{print $1}' | paste -sd, -)"
resolved="$(getent hosts "${mirror#*://}" 2>/dev/null | awk '{print $1}' | paste -sd, -)"

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

Reviewed by Cursor Bugbot for commit 5f03567. Configure here.

ENV PIP_TRUSTED_HOST=${RAYCI_IMAGE_PIP_TRUSTED_HOST}
ENV UV_INSECURE_HOST=${RAYCI_IMAGE_PIP_TRUSTED_HOST}
ARG PIP_INDEX_URL=${RAYCI_IMAGE_PIP_INDEX_URL:-https://pypi.org/simple}
ARG UV_INDEX_URL=${RAYCI_IMAGE_PIP_INDEX_URL:-https://pypi.org/simple}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

CI bases drop inherited pip index

High Severity

Switching PIP_INDEX_URL/UV_INDEX_URL from ENV to ARG on the CI base images covers those builds only and no longer persists into derived images. Downstream Dockerfiles such as base.ml.Dockerfile, base.build.Dockerfile, core.build.Dockerfile, data.build.Dockerfile, and doc.build.Dockerfile install packages with pip/uv but declare no index build-arg, and their wanda specs do not pass RAYCI_IMAGE_PIP_INDEX_URL. Those builds previously inherited the baked index and will now resolve from public PyPI again, re-exposing the files.pythonhosted.org 502 failures this work was meant to avoid. The ARG-only choice fits BYOD images that run outside CI; these bases are CI-only and are the root of that install tree.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 5f03567. Configure here.

@ray-gardener ray-gardener Bot added core Issues that should be addressed in Ray Core devprod labels Aug 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

core Issues that should be addressed in Ray Core devprod

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant