skypilot-nightly 1.0.0.dev20250725__py3-none-any.whl → 1.0.0.dev20250728__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of skypilot-nightly might be problematic. Click here for more details.
- sky/__init__.py +2 -2
- sky/backends/backend_utils.py +117 -56
- sky/backends/cloud_vm_ray_backend.py +1 -1
- sky/clouds/aws.py +1 -1
- sky/clouds/azure.py +1 -1
- sky/clouds/cloud.py +1 -1
- sky/clouds/cudo.py +1 -1
- sky/clouds/do.py +1 -1
- sky/clouds/fluidstack.py +1 -1
- sky/clouds/gcp.py +1 -1
- sky/clouds/hyperbolic.py +1 -1
- sky/clouds/ibm.py +1 -1
- sky/clouds/kubernetes.py +11 -9
- sky/clouds/lambda_cloud.py +1 -1
- sky/clouds/nebius.py +1 -1
- sky/clouds/oci.py +1 -1
- sky/clouds/paperspace.py +1 -1
- sky/clouds/runpod.py +1 -1
- sky/clouds/scp.py +1 -1
- sky/clouds/vast.py +1 -1
- sky/clouds/vsphere.py +1 -1
- sky/dashboard/out/404.html +1 -1
- sky/dashboard/out/clusters/[cluster]/[job].html +1 -1
- sky/dashboard/out/clusters/[cluster].html +1 -1
- sky/dashboard/out/clusters.html +1 -1
- sky/dashboard/out/config.html +1 -1
- sky/dashboard/out/index.html +1 -1
- sky/dashboard/out/infra/[context].html +1 -1
- sky/dashboard/out/infra.html +1 -1
- sky/dashboard/out/jobs/[job].html +1 -1
- sky/dashboard/out/jobs.html +1 -1
- sky/dashboard/out/users.html +1 -1
- sky/dashboard/out/volumes.html +1 -1
- sky/dashboard/out/workspace/new.html +1 -1
- sky/dashboard/out/workspaces/[name].html +1 -1
- sky/dashboard/out/workspaces.html +1 -1
- sky/exceptions.py +1 -0
- sky/jobs/utils.py +5 -0
- sky/provision/kubernetes/utils.py +9 -0
- sky/provision/kubernetes/volume.py +1 -1
- sky/resources.py +1 -1
- sky/skylet/job_lib.py +4 -0
- sky/skylet/log_lib.py +5 -3
- sky/task.py +1 -1
- sky/templates/kubernetes-ray.yml.j2 +6 -0
- sky/utils/schemas.py +1 -1
- sky/utils/volume.py +78 -0
- sky/volumes/__init__.py +13 -0
- sky/volumes/client/sdk.py +19 -2
- sky/volumes/server/server.py +1 -1
- sky/volumes/utils.py +1 -1
- sky/volumes/volume.py +0 -73
- {skypilot_nightly-1.0.0.dev20250725.dist-info → skypilot_nightly-1.0.0.dev20250728.dist-info}/METADATA +13 -2
- {skypilot_nightly-1.0.0.dev20250725.dist-info → skypilot_nightly-1.0.0.dev20250728.dist-info}/RECORD +60 -59
- /sky/dashboard/out/_next/static/{SiA7c33x_DqO42M373Okd → ucBqsWPN0A5D2kXj8-FqQ}/_buildManifest.js +0 -0
- /sky/dashboard/out/_next/static/{SiA7c33x_DqO42M373Okd → ucBqsWPN0A5D2kXj8-FqQ}/_ssgManifest.js +0 -0
- {skypilot_nightly-1.0.0.dev20250725.dist-info → skypilot_nightly-1.0.0.dev20250728.dist-info}/WHEEL +0 -0
- {skypilot_nightly-1.0.0.dev20250725.dist-info → skypilot_nightly-1.0.0.dev20250728.dist-info}/entry_points.txt +0 -0
- {skypilot_nightly-1.0.0.dev20250725.dist-info → skypilot_nightly-1.0.0.dev20250728.dist-info}/licenses/LICENSE +0 -0
- {skypilot_nightly-1.0.0.dev20250725.dist-info → skypilot_nightly-1.0.0.dev20250728.dist-info}/top_level.txt +0 -0
sky/dashboard/out/jobs.html
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
<!DOCTYPE html><html><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><meta name="next-head-count" content="2"/><link rel="preload" href="/dashboard/_next/static/css/b3227360726f12eb.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/b3227360726f12eb.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/dashboard/_next/static/chunks/polyfills-78c92fac7aa8fdd8.js"></script><script src="/dashboard/_next/static/chunks/webpack-a305898dc479711e.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-efc06c2733009cd3.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-c0a4f1ea606d48d2.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-da491665d4289aae.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/jobs-49f790d12a85027c.js" defer=""></script><script src="/dashboard/_next/static/
|
|
1
|
+
<!DOCTYPE html><html><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><meta name="next-head-count" content="2"/><link rel="preload" href="/dashboard/_next/static/css/b3227360726f12eb.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/b3227360726f12eb.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/dashboard/_next/static/chunks/polyfills-78c92fac7aa8fdd8.js"></script><script src="/dashboard/_next/static/chunks/webpack-a305898dc479711e.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-efc06c2733009cd3.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-c0a4f1ea606d48d2.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-da491665d4289aae.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/jobs-49f790d12a85027c.js" defer=""></script><script src="/dashboard/_next/static/ucBqsWPN0A5D2kXj8-FqQ/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/ucBqsWPN0A5D2kXj8-FqQ/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/jobs","query":{},"buildId":"ucBqsWPN0A5D2kXj8-FqQ","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
|
sky/dashboard/out/users.html
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
<!DOCTYPE html><html><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><meta name="next-head-count" content="2"/><link rel="preload" href="/dashboard/_next/static/css/b3227360726f12eb.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/b3227360726f12eb.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/dashboard/_next/static/chunks/polyfills-78c92fac7aa8fdd8.js"></script><script src="/dashboard/_next/static/chunks/webpack-a305898dc479711e.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-efc06c2733009cd3.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-c0a4f1ea606d48d2.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-da491665d4289aae.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/users-6790fcefd5487b13.js" defer=""></script><script src="/dashboard/_next/static/
|
|
1
|
+
<!DOCTYPE html><html><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><meta name="next-head-count" content="2"/><link rel="preload" href="/dashboard/_next/static/css/b3227360726f12eb.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/b3227360726f12eb.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/dashboard/_next/static/chunks/polyfills-78c92fac7aa8fdd8.js"></script><script src="/dashboard/_next/static/chunks/webpack-a305898dc479711e.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-efc06c2733009cd3.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-c0a4f1ea606d48d2.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-da491665d4289aae.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/users-6790fcefd5487b13.js" defer=""></script><script src="/dashboard/_next/static/ucBqsWPN0A5D2kXj8-FqQ/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/ucBqsWPN0A5D2kXj8-FqQ/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/users","query":{},"buildId":"ucBqsWPN0A5D2kXj8-FqQ","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
|
sky/dashboard/out/volumes.html
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
<!DOCTYPE html><html><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><meta name="next-head-count" content="2"/><link rel="preload" href="/dashboard/_next/static/css/b3227360726f12eb.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/b3227360726f12eb.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/dashboard/_next/static/chunks/polyfills-78c92fac7aa8fdd8.js"></script><script src="/dashboard/_next/static/chunks/webpack-a305898dc479711e.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-efc06c2733009cd3.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-c0a4f1ea606d48d2.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-da491665d4289aae.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/volumes-61ea7ba7e56f8d06.js" defer=""></script><script src="/dashboard/_next/static/
|
|
1
|
+
<!DOCTYPE html><html><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><meta name="next-head-count" content="2"/><link rel="preload" href="/dashboard/_next/static/css/b3227360726f12eb.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/b3227360726f12eb.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/dashboard/_next/static/chunks/polyfills-78c92fac7aa8fdd8.js"></script><script src="/dashboard/_next/static/chunks/webpack-a305898dc479711e.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-efc06c2733009cd3.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-c0a4f1ea606d48d2.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-da491665d4289aae.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/volumes-61ea7ba7e56f8d06.js" defer=""></script><script src="/dashboard/_next/static/ucBqsWPN0A5D2kXj8-FqQ/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/ucBqsWPN0A5D2kXj8-FqQ/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/volumes","query":{},"buildId":"ucBqsWPN0A5D2kXj8-FqQ","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<!DOCTYPE html><html><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><meta name="next-head-count" content="2"/><link rel="preload" href="/dashboard/_next/static/css/b3227360726f12eb.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/b3227360726f12eb.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/dashboard/_next/static/chunks/polyfills-78c92fac7aa8fdd8.js"></script><script src="/dashboard/_next/static/chunks/webpack-a305898dc479711e.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-efc06c2733009cd3.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-c0a4f1ea606d48d2.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-da491665d4289aae.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/workspace/new-5629d4e551dba1ee.js" defer=""></script><script src="/dashboard/_next/static/
|
|
1
|
+
<!DOCTYPE html><html><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><meta name="next-head-count" content="2"/><link rel="preload" href="/dashboard/_next/static/css/b3227360726f12eb.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/b3227360726f12eb.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/dashboard/_next/static/chunks/polyfills-78c92fac7aa8fdd8.js"></script><script src="/dashboard/_next/static/chunks/webpack-a305898dc479711e.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-efc06c2733009cd3.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-c0a4f1ea606d48d2.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-da491665d4289aae.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/workspace/new-5629d4e551dba1ee.js" defer=""></script><script src="/dashboard/_next/static/ucBqsWPN0A5D2kXj8-FqQ/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/ucBqsWPN0A5D2kXj8-FqQ/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/workspace/new","query":{},"buildId":"ucBqsWPN0A5D2kXj8-FqQ","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<!DOCTYPE html><html><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><meta name="next-head-count" content="2"/><link rel="preload" href="/dashboard/_next/static/css/b3227360726f12eb.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/b3227360726f12eb.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/dashboard/_next/static/chunks/polyfills-78c92fac7aa8fdd8.js"></script><script src="/dashboard/_next/static/chunks/webpack-a305898dc479711e.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-efc06c2733009cd3.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-c0a4f1ea606d48d2.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-da491665d4289aae.js" defer=""></script><script src="/dashboard/_next/static/chunks/616-162f3033ffcd3d31.js" defer=""></script><script src="/dashboard/_next/static/chunks/5230-df791914b54d91d9.js" defer=""></script><script src="/dashboard/_next/static/chunks/5739-5ea3ffa10fc884f2.js" defer=""></script><script src="/dashboard/_next/static/chunks/1664-d65361e92b85e786.js" defer=""></script><script src="/dashboard/_next/static/chunks/7411-2cc31dc0fdf2a9ad.js" defer=""></script><script src="/dashboard/_next/static/chunks/1272-1ef0bf0237faccdb.js" defer=""></script><script src="/dashboard/_next/static/chunks/1559-18717d96ef2fcbe9.js" defer=""></script><script src="/dashboard/_next/static/chunks/6989-eab0e9c16b64fd9f.js" defer=""></script><script src="/dashboard/_next/static/chunks/3698-9fa11dafb5cad4a6.js" defer=""></script><script src="/dashboard/_next/static/chunks/6135-2abbd0352f8ee061.js" defer=""></script><script src="/dashboard/_next/static/chunks/6990-f64e03df359e04f7.js" defer=""></script><script src="/dashboard/_next/static/chunks/8969-8e0b2055bf5dd499.js" defer=""></script><script src="/dashboard/_next/static/chunks/1043-869d9c78bf5dd3df.js" defer=""></script><script src="/dashboard/_next/static/chunks/6601-d4a381403a8bae91.js" defer=""></script><script src="/dashboard/_next/static/chunks/938-7ee806653aef0609.js" defer=""></script><script src="/dashboard/_next/static/chunks/1141-e49a159c30a6c4a7.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/workspaces/%5Bname%5D-6bcd4b20914d76c9.js" defer=""></script><script src="/dashboard/_next/static/
|
|
1
|
+
<!DOCTYPE html><html><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><meta name="next-head-count" content="2"/><link rel="preload" href="/dashboard/_next/static/css/b3227360726f12eb.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/b3227360726f12eb.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/dashboard/_next/static/chunks/polyfills-78c92fac7aa8fdd8.js"></script><script src="/dashboard/_next/static/chunks/webpack-a305898dc479711e.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-efc06c2733009cd3.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-c0a4f1ea606d48d2.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-da491665d4289aae.js" defer=""></script><script src="/dashboard/_next/static/chunks/616-162f3033ffcd3d31.js" defer=""></script><script src="/dashboard/_next/static/chunks/5230-df791914b54d91d9.js" defer=""></script><script src="/dashboard/_next/static/chunks/5739-5ea3ffa10fc884f2.js" defer=""></script><script src="/dashboard/_next/static/chunks/1664-d65361e92b85e786.js" defer=""></script><script src="/dashboard/_next/static/chunks/7411-2cc31dc0fdf2a9ad.js" defer=""></script><script src="/dashboard/_next/static/chunks/1272-1ef0bf0237faccdb.js" defer=""></script><script src="/dashboard/_next/static/chunks/1559-18717d96ef2fcbe9.js" defer=""></script><script src="/dashboard/_next/static/chunks/6989-eab0e9c16b64fd9f.js" defer=""></script><script src="/dashboard/_next/static/chunks/3698-9fa11dafb5cad4a6.js" defer=""></script><script src="/dashboard/_next/static/chunks/6135-2abbd0352f8ee061.js" defer=""></script><script src="/dashboard/_next/static/chunks/6990-f64e03df359e04f7.js" defer=""></script><script src="/dashboard/_next/static/chunks/8969-8e0b2055bf5dd499.js" defer=""></script><script src="/dashboard/_next/static/chunks/1043-869d9c78bf5dd3df.js" defer=""></script><script src="/dashboard/_next/static/chunks/6601-d4a381403a8bae91.js" defer=""></script><script src="/dashboard/_next/static/chunks/938-7ee806653aef0609.js" defer=""></script><script src="/dashboard/_next/static/chunks/1141-e49a159c30a6c4a7.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/workspaces/%5Bname%5D-6bcd4b20914d76c9.js" defer=""></script><script src="/dashboard/_next/static/ucBqsWPN0A5D2kXj8-FqQ/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/ucBqsWPN0A5D2kXj8-FqQ/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/workspaces/[name]","query":{},"buildId":"ucBqsWPN0A5D2kXj8-FqQ","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<!DOCTYPE html><html><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><meta name="next-head-count" content="2"/><link rel="preload" href="/dashboard/_next/static/css/b3227360726f12eb.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/b3227360726f12eb.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/dashboard/_next/static/chunks/polyfills-78c92fac7aa8fdd8.js"></script><script src="/dashboard/_next/static/chunks/webpack-a305898dc479711e.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-efc06c2733009cd3.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-c0a4f1ea606d48d2.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-da491665d4289aae.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/workspaces-5f7fe4b7d55b8612.js" defer=""></script><script src="/dashboard/_next/static/
|
|
1
|
+
<!DOCTYPE html><html><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><meta name="next-head-count" content="2"/><link rel="preload" href="/dashboard/_next/static/css/b3227360726f12eb.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/b3227360726f12eb.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/dashboard/_next/static/chunks/polyfills-78c92fac7aa8fdd8.js"></script><script src="/dashboard/_next/static/chunks/webpack-a305898dc479711e.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-efc06c2733009cd3.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-c0a4f1ea606d48d2.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-da491665d4289aae.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/workspaces-5f7fe4b7d55b8612.js" defer=""></script><script src="/dashboard/_next/static/ucBqsWPN0A5D2kXj8-FqQ/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/ucBqsWPN0A5D2kXj8-FqQ/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/workspaces","query":{},"buildId":"ucBqsWPN0A5D2kXj8-FqQ","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
|
sky/exceptions.py
CHANGED
sky/jobs/utils.py
CHANGED
|
@@ -733,6 +733,11 @@ def stream_logs_by_id(job_id: int,
|
|
|
733
733
|
start_streaming = True
|
|
734
734
|
if start_streaming:
|
|
735
735
|
print(line, end='', flush=True)
|
|
736
|
+
# Add the "Job finished" message for terminal states
|
|
737
|
+
if managed_job_status.is_terminal():
|
|
738
|
+
print(ux_utils.finishing_message(
|
|
739
|
+
f'Job finished (status: {managed_job_status.value}).'),
|
|
740
|
+
flush=True)
|
|
736
741
|
return '', exceptions.JobExitCode.from_managed_job_status(
|
|
737
742
|
managed_job_status)
|
|
738
743
|
return (f'{colorama.Fore.YELLOW}'
|
|
@@ -73,6 +73,7 @@ class KubernetesHighPerformanceNetworkType(enum.Enum):
|
|
|
73
73
|
(A4/A3 Ultra instances)
|
|
74
74
|
- NEBIUS: Nebius clusters with InfiniBand support for high-throughput,
|
|
75
75
|
low-latency networking
|
|
76
|
+
- COREWEAVE: CoreWeave clusters with InfiniBand support.
|
|
76
77
|
- NONE: Standard clusters without specialized networking optimizations
|
|
77
78
|
|
|
78
79
|
The network configurations align with corresponding VM-based
|
|
@@ -86,6 +87,7 @@ class KubernetesHighPerformanceNetworkType(enum.Enum):
|
|
|
86
87
|
GCP_TCPXO = 'gcp_tcpxo'
|
|
87
88
|
GCP_GPUDIRECT_RDMA = 'gcp_gpudirect_rdma'
|
|
88
89
|
NEBIUS = 'nebius'
|
|
90
|
+
COREWEAVE = 'coreweave'
|
|
89
91
|
NONE = 'none'
|
|
90
92
|
|
|
91
93
|
def get_network_env_vars(self) -> Dict[str, str]:
|
|
@@ -97,6 +99,13 @@ class KubernetesHighPerformanceNetworkType(enum.Enum):
|
|
|
97
99
|
'UCX_NET_DEVICES': ('mlx5_0:1,mlx5_1:1,mlx5_2:1,mlx5_3:1,'
|
|
98
100
|
'mlx5_4:1,mlx5_5:1,mlx5_6:1,mlx5_7:1')
|
|
99
101
|
}
|
|
102
|
+
elif self == KubernetesHighPerformanceNetworkType.COREWEAVE:
|
|
103
|
+
return {
|
|
104
|
+
'NCCL_SOCKET_IFNAME': 'eth0',
|
|
105
|
+
'NCCL_IB_HCA': 'ibp',
|
|
106
|
+
'UCX_NET_DEVICES': ('ibp0:1,ibp1:1,ibp2:1,ibp3:1,'
|
|
107
|
+
'ibp4:1,ibp5:1,ibp6:1,ibp7:1')
|
|
108
|
+
}
|
|
100
109
|
else:
|
|
101
110
|
# GCP clusters and generic clusters - environment variables are
|
|
102
111
|
# handled directly in the template
|
|
@@ -8,7 +8,7 @@ from sky.adaptors import kubernetes
|
|
|
8
8
|
from sky.provision.kubernetes import config as config_lib
|
|
9
9
|
from sky.provision.kubernetes import constants as k8s_constants
|
|
10
10
|
from sky.provision.kubernetes import utils as kubernetes_utils
|
|
11
|
-
from sky.
|
|
11
|
+
from sky.utils import volume as volume_lib
|
|
12
12
|
|
|
13
13
|
logger = sky_logging.init_logger(__name__)
|
|
14
14
|
|
sky/resources.py
CHANGED
sky/skylet/job_lib.py
CHANGED
|
@@ -1185,6 +1185,10 @@ class JobLibCodeGen:
|
|
|
1185
1185
|
# and older did not have JobExitCode, so we use 0 for those versions
|
|
1186
1186
|
# TODO: Remove this special handling after 0.10.0.
|
|
1187
1187
|
'exit_code = exceptions.JobExitCode.from_job_status(job_status) if getattr(constants, "SKYLET_LIB_VERSION", 1) > 2 else 0',
|
|
1188
|
+
# Fix for dashboard: When follow=False and job is still running (NOT_FINISHED=101),
|
|
1189
|
+
# exit with success (0) since fetching current logs is a successful operation.
|
|
1190
|
+
# This prevents shell wrappers from printing "command terminated with exit code 101".
|
|
1191
|
+
f'exit_code = 0 if not {follow} and exit_code == 101 else exit_code',
|
|
1188
1192
|
'sys.exit(exit_code)',
|
|
1189
1193
|
]
|
|
1190
1194
|
return cls._build(code)
|
sky/skylet/log_lib.py
CHANGED
|
@@ -544,9 +544,11 @@ def tail_logs(job_id: Optional[int],
|
|
|
544
544
|
if start_streaming:
|
|
545
545
|
print(line, end='', flush=True)
|
|
546
546
|
status_str = status.value if status is not None else 'None'
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
547
|
+
# Only show "Job finished" for actually terminal states
|
|
548
|
+
if status is not None and status.is_terminal():
|
|
549
|
+
print(ux_utils.finishing_message(
|
|
550
|
+
f'Job finished (status: {status_str}).'),
|
|
551
|
+
flush=True)
|
|
550
552
|
except FileNotFoundError:
|
|
551
553
|
print(f'{colorama.Fore.RED}ERROR: Logs for job {job_id} (status:'
|
|
552
554
|
f' {status.value}) does not exist.{colorama.Style.RESET_ALL}')
|
sky/task.py
CHANGED
|
@@ -24,7 +24,7 @@ from sky.skylet import constants
|
|
|
24
24
|
from sky.utils import common_utils
|
|
25
25
|
from sky.utils import schemas
|
|
26
26
|
from sky.utils import ux_utils
|
|
27
|
-
from sky.
|
|
27
|
+
from sky.utils import volume as volume_lib
|
|
28
28
|
|
|
29
29
|
if typing.TYPE_CHECKING:
|
|
30
30
|
import yaml
|
|
@@ -1008,12 +1008,18 @@ available_node_types:
|
|
|
1008
1008
|
# https://cloud.google.com/kubernetes-engine/docs/concepts/tpus#how_tpus_work
|
|
1009
1009
|
{{k8s_resource_key}}: {{accelerator_count}}
|
|
1010
1010
|
{% endif %}
|
|
1011
|
+
{% if k8s_network_type == 'coreweave' %}
|
|
1012
|
+
rdma/ib: 1
|
|
1013
|
+
{% endif %}
|
|
1011
1014
|
{% if k8s_resource_key is not none %}
|
|
1012
1015
|
limits:
|
|
1013
1016
|
# Limits need to be defined for GPU/TPU requests
|
|
1014
1017
|
{% if k8s_resource_key is not none %}
|
|
1015
1018
|
{{k8s_resource_key}}: {{accelerator_count}}
|
|
1016
1019
|
{% endif %}
|
|
1020
|
+
{% if k8s_network_type == 'coreweave' %}
|
|
1021
|
+
rdma/ib: 1
|
|
1022
|
+
{% endif %}
|
|
1017
1023
|
{% endif %}
|
|
1018
1024
|
{% if k8s_ipc_lock_capability %}
|
|
1019
1025
|
securityContext:
|
sky/utils/schemas.py
CHANGED
|
@@ -421,7 +421,7 @@ def get_resources_schema():
|
|
|
421
421
|
|
|
422
422
|
def get_volume_schema():
|
|
423
423
|
# pylint: disable=import-outside-toplevel
|
|
424
|
-
from sky.
|
|
424
|
+
from sky.utils import volume
|
|
425
425
|
|
|
426
426
|
return {
|
|
427
427
|
'$schema': 'https://json-schema.org/draft/2020-12/schema',
|
sky/utils/volume.py
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"""Volume utilities."""
|
|
2
|
+
import enum
|
|
3
|
+
import time
|
|
4
|
+
from typing import Any, Dict
|
|
5
|
+
|
|
6
|
+
from sky import exceptions
|
|
7
|
+
from sky import global_user_state
|
|
8
|
+
from sky import models
|
|
9
|
+
from sky.utils import common_utils
|
|
10
|
+
from sky.utils import schemas
|
|
11
|
+
from sky.utils import status_lib
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class VolumeAccessMode(enum.Enum):
|
|
15
|
+
"""Volume access mode."""
|
|
16
|
+
READ_WRITE_ONCE = 'ReadWriteOnce'
|
|
17
|
+
READ_WRITE_ONCE_POD = 'ReadWriteOncePod'
|
|
18
|
+
READ_WRITE_MANY = 'ReadWriteMany'
|
|
19
|
+
READ_ONLY_MANY = 'ReadOnlyMany'
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class VolumeType(enum.Enum):
|
|
23
|
+
"""Volume type."""
|
|
24
|
+
PVC = 'k8s-pvc'
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class VolumeMount:
|
|
28
|
+
"""Volume mount specification."""
|
|
29
|
+
|
|
30
|
+
def __init__(self, path: str, volume_name: str,
|
|
31
|
+
volume_config: models.VolumeConfig):
|
|
32
|
+
self.path: str = path
|
|
33
|
+
self.volume_name: str = volume_name
|
|
34
|
+
self.volume_config: models.VolumeConfig = volume_config
|
|
35
|
+
|
|
36
|
+
def pre_mount(self) -> None:
|
|
37
|
+
"""Update the volume status before actual mounting."""
|
|
38
|
+
# TODO(aylei): for ReadWriteOnce volume, we also need to queue the
|
|
39
|
+
# mount request if the target volume is already mounted to another
|
|
40
|
+
# cluster. For now, we only support ReadWriteMany volume.
|
|
41
|
+
global_user_state.update_volume(self.volume_name,
|
|
42
|
+
last_attached_at=int(time.time()),
|
|
43
|
+
status=status_lib.VolumeStatus.IN_USE)
|
|
44
|
+
|
|
45
|
+
@classmethod
|
|
46
|
+
def resolve(cls, path: str, volume_name: str) -> 'VolumeMount':
|
|
47
|
+
"""Resolve the volume mount by populating metadata of volume."""
|
|
48
|
+
record = global_user_state.get_volume_by_name(volume_name)
|
|
49
|
+
if record is None:
|
|
50
|
+
raise exceptions.VolumeNotFoundError(
|
|
51
|
+
f'Volume {volume_name} not found.')
|
|
52
|
+
assert 'handle' in record, 'Volume handle is None.'
|
|
53
|
+
volume_config: models.VolumeConfig = record['handle']
|
|
54
|
+
return cls(path, volume_name, volume_config)
|
|
55
|
+
|
|
56
|
+
@classmethod
|
|
57
|
+
def from_yaml_config(cls, config: Dict[str, Any]) -> 'VolumeMount':
|
|
58
|
+
common_utils.validate_schema(config, schemas.get_volume_mount_schema(),
|
|
59
|
+
'Invalid volume mount config: ')
|
|
60
|
+
|
|
61
|
+
path = config.pop('path', None)
|
|
62
|
+
volume_name = config.pop('volume_name', None)
|
|
63
|
+
volume_config: models.VolumeConfig = models.VolumeConfig.model_validate(
|
|
64
|
+
config.pop('volume_config', None))
|
|
65
|
+
return cls(path, volume_name, volume_config)
|
|
66
|
+
|
|
67
|
+
def to_yaml_config(self) -> Dict[str, Any]:
|
|
68
|
+
return {
|
|
69
|
+
'path': self.path,
|
|
70
|
+
'volume_name': self.volume_name,
|
|
71
|
+
'volume_config': self.volume_config.model_dump(),
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
def __repr__(self):
|
|
75
|
+
return (f'VolumeMount('
|
|
76
|
+
f'\n\tpath={self.path},'
|
|
77
|
+
f'\n\tvolume_name={self.volume_name},'
|
|
78
|
+
f'\n\tvolume_config={self.volume_config})')
|
sky/volumes/__init__.py
CHANGED
sky/volumes/client/sdk.py
CHANGED
|
@@ -26,6 +26,12 @@ logger = sky_logging.init_logger(__name__)
|
|
|
26
26
|
@annotations.client_api
|
|
27
27
|
def apply(volume: volume_lib.Volume) -> server_common.RequestId:
|
|
28
28
|
"""Creates or registers a volume.
|
|
29
|
+
|
|
30
|
+
Args:
|
|
31
|
+
volume: The volume to apply.
|
|
32
|
+
|
|
33
|
+
Returns:
|
|
34
|
+
The request ID of the apply request.
|
|
29
35
|
"""
|
|
30
36
|
body = payloads.VolumeApplyBody(name=volume.name,
|
|
31
37
|
volume_type=volume.type,
|
|
@@ -45,7 +51,11 @@ def apply(volume: volume_lib.Volume) -> server_common.RequestId:
|
|
|
45
51
|
@server_common.check_server_healthy_or_start
|
|
46
52
|
@annotations.client_api
|
|
47
53
|
def ls() -> server_common.RequestId:
|
|
48
|
-
"""Lists all volumes.
|
|
54
|
+
"""Lists all volumes.
|
|
55
|
+
|
|
56
|
+
Returns:
|
|
57
|
+
The request ID of the list request.
|
|
58
|
+
"""
|
|
49
59
|
response = requests.get(f'{server_common.get_server_url()}/volumes',
|
|
50
60
|
cookies=server_common.get_api_cookie_jar())
|
|
51
61
|
return server_common.get_request_id(response)
|
|
@@ -56,7 +66,14 @@ def ls() -> server_common.RequestId:
|
|
|
56
66
|
@server_common.check_server_healthy_or_start
|
|
57
67
|
@annotations.client_api
|
|
58
68
|
def delete(names: List[str]) -> server_common.RequestId:
|
|
59
|
-
"""Deletes
|
|
69
|
+
"""Deletes volumes.
|
|
70
|
+
|
|
71
|
+
Args:
|
|
72
|
+
names: List of volume names to delete.
|
|
73
|
+
|
|
74
|
+
Returns:
|
|
75
|
+
The request ID of the delete request.
|
|
76
|
+
"""
|
|
60
77
|
body = payloads.VolumeDeleteBody(names=names)
|
|
61
78
|
response = requests.post(f'{server_common.get_server_url()}/volumes/delete',
|
|
62
79
|
json=json.loads(body.model_dump_json()),
|
sky/volumes/server/server.py
CHANGED
|
@@ -8,7 +8,7 @@ from sky import sky_logging
|
|
|
8
8
|
from sky.server.requests import executor
|
|
9
9
|
from sky.server.requests import payloads
|
|
10
10
|
from sky.server.requests import requests as requests_lib
|
|
11
|
-
from sky.
|
|
11
|
+
from sky.utils import volume
|
|
12
12
|
from sky.volumes.server import core
|
|
13
13
|
|
|
14
14
|
logger = sky_logging.init_logger(__name__)
|
sky/volumes/utils.py
CHANGED
sky/volumes/volume.py
CHANGED
|
@@ -1,83 +1,10 @@
|
|
|
1
1
|
"""Volume types and access modes."""
|
|
2
|
-
import enum
|
|
3
|
-
import time
|
|
4
2
|
from typing import Any, Dict, Optional
|
|
5
3
|
|
|
6
|
-
from sky import exceptions
|
|
7
|
-
from sky import global_user_state
|
|
8
|
-
from sky import models
|
|
9
4
|
from sky.utils import common_utils
|
|
10
5
|
from sky.utils import infra_utils
|
|
11
6
|
from sky.utils import resources_utils
|
|
12
7
|
from sky.utils import schemas
|
|
13
|
-
from sky.utils import status_lib
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
class VolumeType(enum.Enum):
|
|
17
|
-
"""Volume type."""
|
|
18
|
-
PVC = 'k8s-pvc'
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
class VolumeAccessMode(enum.Enum):
|
|
22
|
-
"""Volume access mode."""
|
|
23
|
-
READ_WRITE_ONCE = 'ReadWriteOnce'
|
|
24
|
-
READ_WRITE_ONCE_POD = 'ReadWriteOncePod'
|
|
25
|
-
READ_WRITE_MANY = 'ReadWriteMany'
|
|
26
|
-
READ_ONLY_MANY = 'ReadOnlyMany'
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
class VolumeMount:
|
|
30
|
-
"""Volume mount specification."""
|
|
31
|
-
|
|
32
|
-
def __init__(self, path: str, volume_name: str,
|
|
33
|
-
volume_config: models.VolumeConfig):
|
|
34
|
-
self.path: str = path
|
|
35
|
-
self.volume_name: str = volume_name
|
|
36
|
-
self.volume_config: models.VolumeConfig = volume_config
|
|
37
|
-
|
|
38
|
-
def pre_mount(self) -> None:
|
|
39
|
-
"""Update the volume status before actual mounting."""
|
|
40
|
-
# TODO(aylei): for ReadWriteOnce volume, we also need to queue the
|
|
41
|
-
# mount request if the target volume is already mounted to another
|
|
42
|
-
# cluster. For now, we only support ReadWriteMany volume.
|
|
43
|
-
global_user_state.update_volume(self.volume_name,
|
|
44
|
-
last_attached_at=int(time.time()),
|
|
45
|
-
status=status_lib.VolumeStatus.IN_USE)
|
|
46
|
-
|
|
47
|
-
@classmethod
|
|
48
|
-
def resolve(cls, path: str, volume_name: str) -> 'VolumeMount':
|
|
49
|
-
"""Resolve the volume mount by populating metadata of volume."""
|
|
50
|
-
record = global_user_state.get_volume_by_name(volume_name)
|
|
51
|
-
if record is None:
|
|
52
|
-
raise exceptions.VolumeNotFoundError(
|
|
53
|
-
f'Volume {volume_name} not found.')
|
|
54
|
-
assert 'handle' in record, 'Volume handle is None.'
|
|
55
|
-
volume_config: models.VolumeConfig = record['handle']
|
|
56
|
-
return cls(path, volume_name, volume_config)
|
|
57
|
-
|
|
58
|
-
@classmethod
|
|
59
|
-
def from_yaml_config(cls, config: Dict[str, Any]) -> 'VolumeMount':
|
|
60
|
-
common_utils.validate_schema(config, schemas.get_volume_mount_schema(),
|
|
61
|
-
'Invalid volume mount config: ')
|
|
62
|
-
|
|
63
|
-
path = config.pop('path', None)
|
|
64
|
-
volume_name = config.pop('volume_name', None)
|
|
65
|
-
volume_config: models.VolumeConfig = models.VolumeConfig.model_validate(
|
|
66
|
-
config.pop('volume_config', None))
|
|
67
|
-
return cls(path, volume_name, volume_config)
|
|
68
|
-
|
|
69
|
-
def to_yaml_config(self) -> Dict[str, Any]:
|
|
70
|
-
return {
|
|
71
|
-
'path': self.path,
|
|
72
|
-
'volume_name': self.volume_name,
|
|
73
|
-
'volume_config': self.volume_config.model_dump(),
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
def __repr__(self):
|
|
77
|
-
return (f'VolumeMount('
|
|
78
|
-
f'\n\tpath={self.path},'
|
|
79
|
-
f'\n\tvolume_name={self.volume_name},'
|
|
80
|
-
f'\n\tvolume_config={self.volume_config})')
|
|
81
8
|
|
|
82
9
|
|
|
83
10
|
class Volume:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: skypilot-nightly
|
|
3
|
-
Version: 1.0.0.
|
|
3
|
+
Version: 1.0.0.dev20250728
|
|
4
4
|
Summary: SkyPilot: Run AI on Any Infra — Unified, Faster, Cheaper.
|
|
5
5
|
Author: SkyPilot Team
|
|
6
6
|
License: Apache 2.0
|
|
@@ -224,8 +224,20 @@ Dynamic: summary
|
|
|
224
224
|
Run AI on Any Infra — Unified, Faster, Cheaper
|
|
225
225
|
</h3>
|
|
226
226
|
|
|
227
|
+
<div align="center">
|
|
228
|
+
|
|
229
|
+
#### [🌟 **SkyPilot Demo** 🌟: Click to see a 1-minute tour](https://demo.skypilot.co/dashboard/)
|
|
230
|
+
|
|
231
|
+
</div>
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
|
|
227
235
|
----
|
|
236
|
+
|
|
228
237
|
:fire: *News* :fire:
|
|
238
|
+
- [Jul 2025] 🎉 SkyPilot v0.10.0 released! [**blog post**](https://blog.skypilot.co/announcing-skypilot-0.10.0/), [**release notes**](https://github.com/skypilot-org/skypilot/releases/tag/v0.10.0)
|
|
239
|
+
- [Jul 2025] Finetune **Llama4** on any distributed cluster/cloud: [**example**](./llm/llama-4-finetuning/)
|
|
240
|
+
- [Jul 2025] Two-part blog series, `The Evolution of AI Job Orchestration`: (1) [Running AI jobs on GPU Neoclouds](https://blog.skypilot.co/ai-job-orchestration-pt1-gpu-neoclouds/), (2) [The AI-Native Control Plane & Orchestration that Finally Works for ML](https://blog.skypilot.co/ai-job-orchestration-pt2-ai-control-plane/)
|
|
229
241
|
- [Apr 2025] Spin up **Qwen3** on your cluster/cloud: [**example**](./llm/qwen/)
|
|
230
242
|
- [Mar 2025] Run and serve **Google Gemma 3** using SkyPilot [**example**](./llm/gemma3/)
|
|
231
243
|
- [Feb 2025] Prepare and serve **Retrieval Augmented Generation (RAG) with DeepSeek-R1**: [**blog post**](https://blog.skypilot.co/deepseek-rag), [**example**](./llm/rag/)
|
|
@@ -233,7 +245,6 @@ Dynamic: summary
|
|
|
233
245
|
- [Feb 2025] Prepare and serve large-scale image search with **vector databases**: [**blog post**](https://blog.skypilot.co/large-scale-vector-database/), [**example**](./examples/vector_database/)
|
|
234
246
|
- [Jan 2025] Launch and serve distilled models from **[DeepSeek-R1](https://github.com/deepseek-ai/DeepSeek-R1)** and **[Janus](https://github.com/deepseek-ai/DeepSeek-Janus)** on Kubernetes or any cloud: [**R1 example**](./llm/deepseek-r1-distilled/) and [**Janus example**](./llm/deepseek-janus/)
|
|
235
247
|
- [Oct 2024] :tada: **SkyPilot crossed 1M+ downloads** :tada:: Thank you to our community! [**Twitter/X**](https://x.com/skypilot_org/status/1844770841718067638)
|
|
236
|
-
- [Sep 2024] Point, launch and serve **Llama 3.2** on Kubernetes or any cloud: [**example**](./llm/llama-3_2/)
|
|
237
248
|
|
|
238
249
|
|
|
239
250
|
**LLM Finetuning Cookbooks**: Finetuning Llama 2 / Llama 3.1 in your own cloud environment, privately: Llama 2 [**example**](./llm/vicuna-llama-2/) and [**blog**](https://blog.skypilot.co/finetuning-llama2-operational-guide/); Llama 3.1 [**example**](./llm/llama-3_1-finetuning/) and [**blog**](https://blog.skypilot.co/finetune-llama-3_1-on-your-infra/)
|