-
Stefy Lanza (nextime / spora ) authored
RunPod ties a network volume to a single data centre, and a pod elsewhere cannot attach it. So `network_volume_id` made `_data_centers()` answer with the volume's region and throw the `data_centers` fallback list away — which is correct for one volume and still forced a choice nobody should make: rent wherever a card is free and re-download the weights onto every cold pod, or keep the storage and wait for capacity in one region. On a contended card that is a lease that fills versus one that waits. `network_volumes` is a map {REGION: volume_id} on the account block and on a model's. The region is chosen first — the scaler already paired every candidate card with every allowed region — and the volume now follows the region that candidate was ranked for. A region with no volume in the map is dropped from the list with a line saying which, because a pod rented there would silently have no storage and boot minutes slower; if nothing is left, provisioning refuses and names both sets rather than placing the data somewhere the operator never listed. A model's map replaces the account's whole rather than merging: listing regions is a statement about where that model's data may live. `network_volume_id` keeps working unchanged and a one-entry map behaves identically to it, which is how this ships without touching any install. The global volume was supposed to make all of this unnecessary and cannot: the type is not creatable through the public API (POST /v2/network-volumes takes only STANDARD|HIGH_PERFORMANCE and demands a dataCenter), and object storage — no locking, no atomic rename, eventual consistency — is wrong for anything but read-mostly weights. `global_volume_id` stays supported; it stops being the plan. Seeding a new region needs no new pod shape: POST /admin/api/runpod/seed-volumes boots one ordinary pod per region with that region's volume attached, which IS the download because the caches already point there, then terminates it. Sequential, admin-only, under the usual spend caps. The venv needs nothing — venv_on_volume already builds it under a lock with .ready written last, so the first pod in a region builds it and every pod after finds it, which is what makes the dependency-free slim image usable in every region. Also here: _data_centers() upper-cases region ids, since the map's key matching the candidate's region is the whole mechanism; pools_schedule_status carries the map; both admin surfaces gained a "Per-region volumes" field. Everything is offline-tested only — 25 new tests in tests/test_runpod_regional_volumes.py. The first multi-region install is the real proof, and the first thing to check there is that RunPod's dataCenterId and the map's key are spelled the same. test_runpod_placement's region test counted three copies of `sel.get("_dc") or self._data_center()`; the region is now resolved once into a local because the volume lookup needs it too, so it checks that one resolution and its uses instead of duplicates of it. Co-Authored-By:Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PxYHWbCAjjjD7A1rhFKtaW
b95384ac