skypilot-nightly 1.0.0.dev20250829__py3-none-any.whl → 1.0.0.dev20250831__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/adaptors/nebius.py +24 -2
- sky/backends/backend_utils.py +39 -36
- sky/backends/cloud_vm_ray_backend.py +37 -0
- sky/client/cli/command.py +17 -6
- sky/client/common.py +5 -4
- sky/client/sdk.py +5 -0
- sky/client/sdk_async.py +8 -2
- sky/core.py +8 -3
- 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/pools/[pool].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/jobs/server/server.py +1 -2
- sky/provision/docker_utils.py +1 -1
- sky/provision/kubernetes/utils.py +39 -26
- sky/serve/server/server.py +1 -2
- sky/server/requests/executor.py +1 -1
- sky/server/requests/payloads.py +1 -0
- sky/server/requests/preconditions.py +2 -3
- sky/server/requests/requests.py +29 -110
- sky/server/server.py +4 -4
- sky/server/stream_utils.py +5 -7
- sky/setup_files/dependencies.py +24 -12
- sky/setup_files/setup.py +2 -0
- sky/utils/db/db_utils.py +0 -11
- sky/utils/schemas.py +6 -0
- {skypilot_nightly-1.0.0.dev20250829.dist-info → skypilot_nightly-1.0.0.dev20250831.dist-info}/METADATA +35 -53
- {skypilot_nightly-1.0.0.dev20250829.dist-info → skypilot_nightly-1.0.0.dev20250831.dist-info}/RECORD +47 -47
- /sky/dashboard/out/_next/static/{hYJYFIxp_ZFONR4wTIJqZ → FtHzmn6BMJ5PzqHhEY51g}/_buildManifest.js +0 -0
- /sky/dashboard/out/_next/static/{hYJYFIxp_ZFONR4wTIJqZ → FtHzmn6BMJ5PzqHhEY51g}/_ssgManifest.js +0 -0
- {skypilot_nightly-1.0.0.dev20250829.dist-info → skypilot_nightly-1.0.0.dev20250831.dist-info}/WHEEL +0 -0
- {skypilot_nightly-1.0.0.dev20250829.dist-info → skypilot_nightly-1.0.0.dev20250831.dist-info}/entry_points.txt +0 -0
- {skypilot_nightly-1.0.0.dev20250829.dist-info → skypilot_nightly-1.0.0.dev20250831.dist-info}/licenses/LICENSE +0 -0
- {skypilot_nightly-1.0.0.dev20250829.dist-info → skypilot_nightly-1.0.0.dev20250831.dist-info}/top_level.txt +0 -0
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/4614e06482d7309e.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/4614e06482d7309e.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-6e76f636a048e145.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-cf60a09ccd051a10.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-f15ccb73239a3bf1.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-ce361c6959bc2001.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/users-018bf31cda52e11b.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/4614e06482d7309e.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/4614e06482d7309e.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-6e76f636a048e145.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-cf60a09ccd051a10.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-f15ccb73239a3bf1.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-ce361c6959bc2001.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/users-018bf31cda52e11b.js" defer=""></script><script src="/dashboard/_next/static/FtHzmn6BMJ5PzqHhEY51g/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/FtHzmn6BMJ5PzqHhEY51g/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/users","query":{},"buildId":"FtHzmn6BMJ5PzqHhEY51g","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/4614e06482d7309e.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/4614e06482d7309e.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-6e76f636a048e145.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-cf60a09ccd051a10.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-f15ccb73239a3bf1.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-ce361c6959bc2001.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/volumes-739726d6b823f532.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/4614e06482d7309e.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/4614e06482d7309e.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-6e76f636a048e145.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-cf60a09ccd051a10.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-f15ccb73239a3bf1.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-ce361c6959bc2001.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/volumes-739726d6b823f532.js" defer=""></script><script src="/dashboard/_next/static/FtHzmn6BMJ5PzqHhEY51g/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/FtHzmn6BMJ5PzqHhEY51g/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/volumes","query":{},"buildId":"FtHzmn6BMJ5PzqHhEY51g","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/4614e06482d7309e.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/4614e06482d7309e.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-6e76f636a048e145.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-cf60a09ccd051a10.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-f15ccb73239a3bf1.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-ce361c6959bc2001.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/workspace/new-3f88a1c7e86a3f86.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/4614e06482d7309e.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/4614e06482d7309e.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-6e76f636a048e145.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-cf60a09ccd051a10.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-f15ccb73239a3bf1.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-ce361c6959bc2001.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/workspace/new-3f88a1c7e86a3f86.js" defer=""></script><script src="/dashboard/_next/static/FtHzmn6BMJ5PzqHhEY51g/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/FtHzmn6BMJ5PzqHhEY51g/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/workspace/new","query":{},"buildId":"FtHzmn6BMJ5PzqHhEY51g","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/4614e06482d7309e.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/4614e06482d7309e.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-6e76f636a048e145.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-cf60a09ccd051a10.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-f15ccb73239a3bf1.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-ce361c6959bc2001.js" defer=""></script><script src="/dashboard/_next/static/chunks/616-3d59f75e2ccf9321.js" defer=""></script><script src="/dashboard/_next/static/chunks/6130-2be46d70a38f1e82.js" defer=""></script><script src="/dashboard/_next/static/chunks/5739-d67458fcb1386c92.js" defer=""></script><script src="/dashboard/_next/static/chunks/7411-b15471acd2cba716.js" defer=""></script><script src="/dashboard/_next/static/chunks/1272-1ef0bf0237faccdb.js" defer=""></script><script src="/dashboard/_next/static/chunks/7205-88191679e7988c57.js" defer=""></script><script src="/dashboard/_next/static/chunks/6989-01359c57e018caa4.js" defer=""></script><script src="/dashboard/_next/static/chunks/3850-ff4a9a69d978632b.js" defer=""></script><script src="/dashboard/_next/static/chunks/8969-4a6f1a928fb6d370.js" defer=""></script><script src="/dashboard/_next/static/chunks/6990-08b2a1cae076a943.js" defer=""></script><script src="/dashboard/_next/static/chunks/6135-4b4d5e824b7f9d3c.js" defer=""></script><script src="/dashboard/_next/static/chunks/1121-8afcf719ea87debc.js" defer=""></script><script src="/dashboard/_next/static/chunks/6601-06114c982db410b6.js" defer=""></script><script src="/dashboard/_next/static/chunks/3015-6c9c09593b1e67b6.js" defer=""></script><script src="/dashboard/_next/static/chunks/1141-943efc7aff0f0c06.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/workspaces/%5Bname%5D-de06e613e20bc977.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/4614e06482d7309e.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/4614e06482d7309e.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-6e76f636a048e145.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-cf60a09ccd051a10.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-f15ccb73239a3bf1.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-ce361c6959bc2001.js" defer=""></script><script src="/dashboard/_next/static/chunks/616-3d59f75e2ccf9321.js" defer=""></script><script src="/dashboard/_next/static/chunks/6130-2be46d70a38f1e82.js" defer=""></script><script src="/dashboard/_next/static/chunks/5739-d67458fcb1386c92.js" defer=""></script><script src="/dashboard/_next/static/chunks/7411-b15471acd2cba716.js" defer=""></script><script src="/dashboard/_next/static/chunks/1272-1ef0bf0237faccdb.js" defer=""></script><script src="/dashboard/_next/static/chunks/7205-88191679e7988c57.js" defer=""></script><script src="/dashboard/_next/static/chunks/6989-01359c57e018caa4.js" defer=""></script><script src="/dashboard/_next/static/chunks/3850-ff4a9a69d978632b.js" defer=""></script><script src="/dashboard/_next/static/chunks/8969-4a6f1a928fb6d370.js" defer=""></script><script src="/dashboard/_next/static/chunks/6990-08b2a1cae076a943.js" defer=""></script><script src="/dashboard/_next/static/chunks/6135-4b4d5e824b7f9d3c.js" defer=""></script><script src="/dashboard/_next/static/chunks/1121-8afcf719ea87debc.js" defer=""></script><script src="/dashboard/_next/static/chunks/6601-06114c982db410b6.js" defer=""></script><script src="/dashboard/_next/static/chunks/3015-6c9c09593b1e67b6.js" defer=""></script><script src="/dashboard/_next/static/chunks/1141-943efc7aff0f0c06.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/workspaces/%5Bname%5D-de06e613e20bc977.js" defer=""></script><script src="/dashboard/_next/static/FtHzmn6BMJ5PzqHhEY51g/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/FtHzmn6BMJ5PzqHhEY51g/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/workspaces/[name]","query":{},"buildId":"FtHzmn6BMJ5PzqHhEY51g","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/4614e06482d7309e.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/4614e06482d7309e.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-6e76f636a048e145.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-cf60a09ccd051a10.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-f15ccb73239a3bf1.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-ce361c6959bc2001.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/workspaces-be35b22e2046564c.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/4614e06482d7309e.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/4614e06482d7309e.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-6e76f636a048e145.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-cf60a09ccd051a10.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-f15ccb73239a3bf1.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-ce361c6959bc2001.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/workspaces-be35b22e2046564c.js" defer=""></script><script src="/dashboard/_next/static/FtHzmn6BMJ5PzqHhEY51g/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/FtHzmn6BMJ5PzqHhEY51g/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/workspaces","query":{},"buildId":"FtHzmn6BMJ5PzqHhEY51g","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
|
sky/jobs/server/server.py
CHANGED
|
@@ -79,8 +79,7 @@ async def logs(
|
|
|
79
79
|
if jobs_logs_body.refresh else api_requests.ScheduleType.SHORT,
|
|
80
80
|
request_cluster_name=common.JOB_CONTROLLER_NAME,
|
|
81
81
|
)
|
|
82
|
-
request_task =
|
|
83
|
-
)
|
|
82
|
+
request_task = api_requests.get_request(request.state.request_id)
|
|
84
83
|
|
|
85
84
|
return stream_utils.stream_response(
|
|
86
85
|
request_id=request_task.request_id,
|
sky/provision/docker_utils.py
CHANGED
|
@@ -371,7 +371,7 @@ class DockerInitializer:
|
|
|
371
371
|
'mkdir -p ~/.ssh;'
|
|
372
372
|
'cat /tmp/host_ssh_authorized_keys >> ~/.ssh/authorized_keys;'
|
|
373
373
|
'sudo service ssh start;'
|
|
374
|
-
'sudo sed -i "s/mesg n/tty -s
|
|
374
|
+
'sudo sed -i "s/mesg n/tty -s \\&\\& mesg n/" ~/.profile;'
|
|
375
375
|
f'{SETUP_ENV_VARS_CMD}',
|
|
376
376
|
run_env='docker')
|
|
377
377
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"""Kubernetes utilities for SkyPilot."""
|
|
2
|
+
import copy
|
|
2
3
|
import dataclasses
|
|
3
4
|
import datetime
|
|
4
5
|
import enum
|
|
@@ -2715,11 +2716,11 @@ def get_endpoint_debug_message(context: Optional[str] = None) -> str:
|
|
|
2715
2716
|
|
|
2716
2717
|
|
|
2717
2718
|
def combine_pod_config_fields(
|
|
2718
|
-
|
|
2719
|
+
cluster_yaml_obj: Dict[str, Any],
|
|
2719
2720
|
cluster_config_overrides: Dict[str, Any],
|
|
2720
2721
|
cloud: Optional[clouds.Cloud] = None,
|
|
2721
2722
|
context: Optional[str] = None,
|
|
2722
|
-
) ->
|
|
2723
|
+
) -> Dict[str, Any]:
|
|
2723
2724
|
"""Adds or updates fields in the YAML with fields from the
|
|
2724
2725
|
~/.sky/config.yaml's kubernetes.pod_spec dict.
|
|
2725
2726
|
This can be used to add fields to the YAML that are not supported by
|
|
@@ -2758,9 +2759,7 @@ def combine_pod_config_fields(
|
|
|
2758
2759
|
- name: my-secret
|
|
2759
2760
|
```
|
|
2760
2761
|
"""
|
|
2761
|
-
|
|
2762
|
-
yaml_content = f.read()
|
|
2763
|
-
yaml_obj = yaml_utils.safe_load(yaml_content)
|
|
2762
|
+
merged_cluster_yaml_obj = copy.deepcopy(cluster_yaml_obj)
|
|
2764
2763
|
# We don't use override_configs in `get_effective_region_config`, as merging
|
|
2765
2764
|
# the pod config requires special handling.
|
|
2766
2765
|
if isinstance(cloud, clouds.SSH):
|
|
@@ -2787,26 +2786,20 @@ def combine_pod_config_fields(
|
|
|
2787
2786
|
|
|
2788
2787
|
# Merge the kubernetes config into the YAML for both head and worker nodes.
|
|
2789
2788
|
config_utils.merge_k8s_configs(
|
|
2790
|
-
|
|
2791
|
-
kubernetes_config)
|
|
2789
|
+
merged_cluster_yaml_obj['available_node_types']['ray_head_default']
|
|
2790
|
+
['node_config'], kubernetes_config)
|
|
2791
|
+
return merged_cluster_yaml_obj
|
|
2792
2792
|
|
|
2793
|
-
# Write the updated YAML back to the file
|
|
2794
|
-
yaml_utils.dump_yaml(cluster_yaml_path, yaml_obj)
|
|
2795
2793
|
|
|
2796
|
-
|
|
2797
|
-
def combine_metadata_fields(cluster_yaml_path: str,
|
|
2794
|
+
def combine_metadata_fields(cluster_yaml_obj: Dict[str, Any],
|
|
2798
2795
|
cluster_config_overrides: Dict[str, Any],
|
|
2799
|
-
context: Optional[str] = None) ->
|
|
2796
|
+
context: Optional[str] = None) -> Dict[str, Any]:
|
|
2800
2797
|
"""Updates the metadata for all Kubernetes objects created by SkyPilot with
|
|
2801
2798
|
fields from the ~/.sky/config.yaml's kubernetes.custom_metadata dict.
|
|
2802
2799
|
|
|
2803
2800
|
Obeys the same add or update semantics as combine_pod_config_fields().
|
|
2804
2801
|
"""
|
|
2805
|
-
|
|
2806
|
-
with open(cluster_yaml_path, 'r', encoding='utf-8') as f:
|
|
2807
|
-
yaml_content = f.read()
|
|
2808
|
-
yaml_obj = yaml_utils.safe_load(yaml_content)
|
|
2809
|
-
|
|
2802
|
+
merged_cluster_yaml_obj = copy.deepcopy(cluster_yaml_obj)
|
|
2810
2803
|
# Get custom_metadata from global config
|
|
2811
2804
|
custom_metadata = skypilot_config.get_effective_region_config(
|
|
2812
2805
|
cloud='kubernetes',
|
|
@@ -2828,22 +2821,42 @@ def combine_metadata_fields(cluster_yaml_path: str,
|
|
|
2828
2821
|
# List of objects in the cluster YAML to be updated
|
|
2829
2822
|
combination_destinations = [
|
|
2830
2823
|
# Service accounts
|
|
2831
|
-
|
|
2832
|
-
yaml_obj['provider']['autoscaler_role']['metadata'],
|
|
2833
|
-
yaml_obj['provider']['autoscaler_role_binding']['metadata'],
|
|
2834
|
-
yaml_obj['provider']['autoscaler_service_account']['metadata'],
|
|
2835
|
-
# Pod spec
|
|
2836
|
-
yaml_obj['available_node_types']['ray_head_default']['node_config']
|
|
2824
|
+
merged_cluster_yaml_obj['provider']['autoscaler_service_account']
|
|
2837
2825
|
['metadata'],
|
|
2826
|
+
merged_cluster_yaml_obj['provider']['autoscaler_role']['metadata'],
|
|
2827
|
+
merged_cluster_yaml_obj['provider']['autoscaler_role_binding']
|
|
2828
|
+
['metadata'],
|
|
2829
|
+
merged_cluster_yaml_obj['provider']['autoscaler_service_account']
|
|
2830
|
+
['metadata'],
|
|
2831
|
+
# Pod spec
|
|
2832
|
+
merged_cluster_yaml_obj['available_node_types']['ray_head_default']
|
|
2833
|
+
['node_config']['metadata'],
|
|
2838
2834
|
# Services for pods
|
|
2839
|
-
*[
|
|
2835
|
+
*[
|
|
2836
|
+
svc['metadata']
|
|
2837
|
+
for svc in merged_cluster_yaml_obj['provider']['services']
|
|
2838
|
+
]
|
|
2840
2839
|
]
|
|
2841
2840
|
|
|
2842
2841
|
for destination in combination_destinations:
|
|
2843
2842
|
config_utils.merge_k8s_configs(destination, custom_metadata)
|
|
2844
2843
|
|
|
2845
|
-
|
|
2846
|
-
|
|
2844
|
+
return merged_cluster_yaml_obj
|
|
2845
|
+
|
|
2846
|
+
|
|
2847
|
+
def combine_pod_config_fields_and_metadata(
|
|
2848
|
+
cluster_yaml_obj: Dict[str, Any],
|
|
2849
|
+
cluster_config_overrides: Dict[str, Any],
|
|
2850
|
+
cloud: Optional[clouds.Cloud] = None,
|
|
2851
|
+
context: Optional[str] = None) -> Dict[str, Any]:
|
|
2852
|
+
"""Combines pod config fields and metadata fields"""
|
|
2853
|
+
combined_yaml_obj = combine_pod_config_fields(cluster_yaml_obj,
|
|
2854
|
+
cluster_config_overrides,
|
|
2855
|
+
cloud, context)
|
|
2856
|
+
combined_yaml_obj = combine_metadata_fields(combined_yaml_obj,
|
|
2857
|
+
cluster_config_overrides,
|
|
2858
|
+
context)
|
|
2859
|
+
return combined_yaml_obj
|
|
2847
2860
|
|
|
2848
2861
|
|
|
2849
2862
|
def merge_custom_metadata(
|
sky/serve/server/server.py
CHANGED
|
@@ -107,8 +107,7 @@ async def tail_logs(
|
|
|
107
107
|
request_cluster_name=common.SKY_SERVE_CONTROLLER_NAME,
|
|
108
108
|
)
|
|
109
109
|
|
|
110
|
-
request_task =
|
|
111
|
-
)
|
|
110
|
+
request_task = api_requests.get_request(request.state.request_id)
|
|
112
111
|
|
|
113
112
|
return stream_utils.stream_response(
|
|
114
113
|
request_id=request_task.request_id,
|
sky/server/requests/executor.py
CHANGED
|
@@ -453,7 +453,7 @@ async def execute_request_coroutine(request: api_requests.Request):
|
|
|
453
453
|
**request_body.to_kwargs())
|
|
454
454
|
|
|
455
455
|
async def poll_task(request_id: str) -> bool:
|
|
456
|
-
request =
|
|
456
|
+
request = api_requests.get_request(request_id)
|
|
457
457
|
if request is None:
|
|
458
458
|
raise RuntimeError('Request not found')
|
|
459
459
|
|
sky/server/requests/payloads.py
CHANGED
|
@@ -309,6 +309,7 @@ class StatusBody(RequestBody):
|
|
|
309
309
|
cluster_names: Optional[List[str]] = None
|
|
310
310
|
refresh: common_lib.StatusRefreshMode = common_lib.StatusRefreshMode.NONE
|
|
311
311
|
all_users: bool = True
|
|
312
|
+
include_credentials: bool = False
|
|
312
313
|
|
|
313
314
|
|
|
314
315
|
class StartBody(RequestBody):
|
|
@@ -98,7 +98,7 @@ class Precondition(abc.ABC):
|
|
|
98
98
|
return False
|
|
99
99
|
|
|
100
100
|
# Check if the request has been cancelled
|
|
101
|
-
request =
|
|
101
|
+
request = api_requests.get_request(self.request_id)
|
|
102
102
|
if request is None:
|
|
103
103
|
logger.error(f'Request {self.request_id} not found')
|
|
104
104
|
return False
|
|
@@ -112,8 +112,7 @@ class Precondition(abc.ABC):
|
|
|
112
112
|
return True
|
|
113
113
|
if status_msg is not None and status_msg != last_status_msg:
|
|
114
114
|
# Update the status message if it has changed.
|
|
115
|
-
|
|
116
|
-
self.request_id) as req:
|
|
115
|
+
with api_requests.update_request(self.request_id) as req:
|
|
117
116
|
assert req is not None, self.request_id
|
|
118
117
|
req.status_msg = status_msg
|
|
119
118
|
last_status_msg = status_msg
|
sky/server/requests/requests.py
CHANGED
|
@@ -13,8 +13,7 @@ import sqlite3
|
|
|
13
13
|
import threading
|
|
14
14
|
import time
|
|
15
15
|
import traceback
|
|
16
|
-
from typing import
|
|
17
|
-
Optional, Tuple)
|
|
16
|
+
from typing import Any, Callable, Dict, Generator, List, Optional, Tuple
|
|
18
17
|
|
|
19
18
|
import colorama
|
|
20
19
|
import filelock
|
|
@@ -403,46 +402,26 @@ _DB = None
|
|
|
403
402
|
_init_db_lock = threading.Lock()
|
|
404
403
|
|
|
405
404
|
|
|
406
|
-
def _init_db_within_lock():
|
|
407
|
-
global _DB
|
|
408
|
-
if _DB is None:
|
|
409
|
-
db_path = os.path.expanduser(
|
|
410
|
-
server_constants.API_SERVER_REQUEST_DB_PATH)
|
|
411
|
-
pathlib.Path(db_path).parents[0].mkdir(parents=True, exist_ok=True)
|
|
412
|
-
_DB = db_utils.SQLiteConn(db_path, create_table)
|
|
413
|
-
|
|
414
|
-
|
|
415
405
|
def init_db(func):
|
|
416
406
|
"""Initialize the database."""
|
|
417
407
|
|
|
418
408
|
@functools.wraps(func)
|
|
419
409
|
def wrapper(*args, **kwargs):
|
|
410
|
+
global _DB
|
|
420
411
|
if _DB is not None:
|
|
421
412
|
return func(*args, **kwargs)
|
|
422
413
|
with _init_db_lock:
|
|
423
|
-
|
|
414
|
+
if _DB is None:
|
|
415
|
+
db_path = os.path.expanduser(
|
|
416
|
+
server_constants.API_SERVER_REQUEST_DB_PATH)
|
|
417
|
+
pathlib.Path(db_path).parents[0].mkdir(parents=True,
|
|
418
|
+
exist_ok=True)
|
|
419
|
+
_DB = db_utils.SQLiteConn(db_path, create_table)
|
|
424
420
|
return func(*args, **kwargs)
|
|
425
421
|
|
|
426
422
|
return wrapper
|
|
427
423
|
|
|
428
424
|
|
|
429
|
-
def init_db_async(func):
|
|
430
|
-
"""Async version of init_db."""
|
|
431
|
-
|
|
432
|
-
@functools.wraps(func)
|
|
433
|
-
async def wrapper(*args, **kwargs):
|
|
434
|
-
if _DB is not None:
|
|
435
|
-
return await func(*args, **kwargs)
|
|
436
|
-
# If _DB is not initialized, init_db_async will be blocked if there
|
|
437
|
-
# is a thread initializing _DB, this is fine since it occurs on process
|
|
438
|
-
# startup.
|
|
439
|
-
with _init_db_lock:
|
|
440
|
-
_init_db_within_lock()
|
|
441
|
-
return await func(*args, **kwargs)
|
|
442
|
-
|
|
443
|
-
return wrapper
|
|
444
|
-
|
|
445
|
-
|
|
446
425
|
def reset_db_and_logs():
|
|
447
426
|
"""Create the database."""
|
|
448
427
|
server_common.clear_local_api_server_database()
|
|
@@ -461,61 +440,28 @@ def request_lock_path(request_id: str) -> str:
|
|
|
461
440
|
@contextlib.contextmanager
|
|
462
441
|
@init_db
|
|
463
442
|
def update_request(request_id: str) -> Generator[Optional[Request], None, None]:
|
|
464
|
-
"""Get
|
|
443
|
+
"""Get a SkyPilot API request."""
|
|
465
444
|
request = _get_request_no_lock(request_id)
|
|
466
445
|
yield request
|
|
467
446
|
if request is not None:
|
|
468
447
|
_add_or_update_request_no_lock(request)
|
|
469
448
|
|
|
470
449
|
|
|
471
|
-
@init_db
|
|
472
|
-
def update_request_async(
|
|
473
|
-
request_id: str) -> AsyncContextManager[Optional[Request]]:
|
|
474
|
-
"""Async version of update_request.
|
|
475
|
-
|
|
476
|
-
Returns an async context manager that yields the request record and
|
|
477
|
-
persists any in-place updates upon exit.
|
|
478
|
-
"""
|
|
479
|
-
|
|
480
|
-
@contextlib.asynccontextmanager
|
|
481
|
-
async def _cm():
|
|
482
|
-
request = await _get_request_no_lock_async(request_id)
|
|
483
|
-
try:
|
|
484
|
-
yield request
|
|
485
|
-
finally:
|
|
486
|
-
if request is not None:
|
|
487
|
-
await _add_or_update_request_no_lock_async(request)
|
|
488
|
-
|
|
489
|
-
return _cm()
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
_get_request_sql = (f'SELECT {", ".join(REQUEST_COLUMNS)} FROM {REQUEST_TABLE} '
|
|
493
|
-
'WHERE request_id LIKE ?')
|
|
494
|
-
|
|
495
|
-
|
|
496
450
|
def _get_request_no_lock(request_id: str) -> Optional[Request]:
|
|
497
451
|
"""Get a SkyPilot API request."""
|
|
498
452
|
assert _DB is not None
|
|
453
|
+
columns_str = ', '.join(REQUEST_COLUMNS)
|
|
499
454
|
with _DB.conn:
|
|
500
455
|
cursor = _DB.conn.cursor()
|
|
501
|
-
cursor.execute(
|
|
456
|
+
cursor.execute(
|
|
457
|
+
f'SELECT {columns_str} FROM {REQUEST_TABLE} '
|
|
458
|
+
'WHERE request_id LIKE ?', (request_id + '%',))
|
|
502
459
|
row = cursor.fetchone()
|
|
503
460
|
if row is None:
|
|
504
461
|
return None
|
|
505
462
|
return Request.from_row(row)
|
|
506
463
|
|
|
507
464
|
|
|
508
|
-
async def _get_request_no_lock_async(request_id: str) -> Optional[Request]:
|
|
509
|
-
"""Async version of _get_request_no_lock."""
|
|
510
|
-
assert _DB is not None
|
|
511
|
-
conn = await _DB.async_conn()
|
|
512
|
-
async with conn.execute(_get_request_sql, (request_id + '%',)) as cursor:
|
|
513
|
-
row = await cursor.fetchone()
|
|
514
|
-
if row is None:
|
|
515
|
-
return None
|
|
516
|
-
return Request.from_row(row)
|
|
517
|
-
|
|
518
|
-
|
|
519
465
|
@init_db
|
|
520
466
|
def get_latest_request_id() -> Optional[str]:
|
|
521
467
|
"""Get the latest request ID."""
|
|
@@ -535,13 +481,6 @@ def get_request(request_id: str) -> Optional[Request]:
|
|
|
535
481
|
return _get_request_no_lock(request_id)
|
|
536
482
|
|
|
537
483
|
|
|
538
|
-
@init_db_async
|
|
539
|
-
async def get_request_async(request_id: str) -> Optional[Request]:
|
|
540
|
-
"""Async version of get_request."""
|
|
541
|
-
async with filelock.AsyncFileLock(request_lock_path(request_id)):
|
|
542
|
-
return await _get_request_no_lock_async(request_id)
|
|
543
|
-
|
|
544
|
-
|
|
545
484
|
@init_db
|
|
546
485
|
def create_if_not_exists(request: Request) -> bool:
|
|
547
486
|
"""Create a SkyPilot API request if it does not exist."""
|
|
@@ -552,16 +491,6 @@ def create_if_not_exists(request: Request) -> bool:
|
|
|
552
491
|
return True
|
|
553
492
|
|
|
554
493
|
|
|
555
|
-
@init_db_async
|
|
556
|
-
async def create_if_not_exists_async(request: Request) -> bool:
|
|
557
|
-
"""Async version of create_if_not_exists."""
|
|
558
|
-
async with filelock.AsyncFileLock(request_lock_path(request.request_id)):
|
|
559
|
-
if await _get_request_no_lock_async(request.request_id) is not None:
|
|
560
|
-
return False
|
|
561
|
-
await _add_or_update_request_no_lock_async(request)
|
|
562
|
-
return True
|
|
563
|
-
|
|
564
|
-
|
|
565
494
|
@init_db
|
|
566
495
|
def get_request_tasks(
|
|
567
496
|
status: Optional[List[RequestStatus]] = None,
|
|
@@ -636,15 +565,16 @@ def get_request_tasks(
|
|
|
636
565
|
return requests
|
|
637
566
|
|
|
638
567
|
|
|
639
|
-
@
|
|
640
|
-
|
|
568
|
+
@init_db
|
|
569
|
+
def get_api_request_ids_start_with(incomplete: str) -> List[str]:
|
|
641
570
|
"""Get a list of API request ids for shell completion."""
|
|
642
571
|
assert _DB is not None
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
572
|
+
with _DB.conn:
|
|
573
|
+
cursor = _DB.conn.cursor()
|
|
574
|
+
# Prioritize alive requests (PENDING, RUNNING) over finished ones,
|
|
575
|
+
# then order by creation time (newest first) within each category.
|
|
576
|
+
cursor.execute(
|
|
577
|
+
f"""SELECT request_id FROM {REQUEST_TABLE}
|
|
648
578
|
WHERE request_id LIKE ?
|
|
649
579
|
ORDER BY
|
|
650
580
|
CASE
|
|
@@ -652,32 +582,21 @@ async def get_api_request_ids_start_with(incomplete: str) -> List[str]:
|
|
|
652
582
|
ELSE 1
|
|
653
583
|
END,
|
|
654
584
|
created_at DESC
|
|
655
|
-
LIMIT 1000""", (f'{incomplete}%',))
|
|
656
|
-
|
|
657
|
-
if rows is None:
|
|
658
|
-
return []
|
|
659
|
-
return [row[0] for row in rows]
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
_add_or_update_request_sql = (f'INSERT OR REPLACE INTO {REQUEST_TABLE} '
|
|
663
|
-
f'({", ".join(REQUEST_COLUMNS)}) VALUES '
|
|
664
|
-
f'({", ".join(["?"] * len(REQUEST_COLUMNS))})')
|
|
585
|
+
LIMIT 1000""", (f'{incomplete}%',))
|
|
586
|
+
return [row[0] for row in cursor.fetchall()]
|
|
665
587
|
|
|
666
588
|
|
|
667
589
|
def _add_or_update_request_no_lock(request: Request):
|
|
668
590
|
"""Add or update a REST request into the database."""
|
|
591
|
+
row = request.to_row()
|
|
592
|
+
key_str = ', '.join(REQUEST_COLUMNS)
|
|
593
|
+
fill_str = ', '.join(['?'] * len(row))
|
|
669
594
|
assert _DB is not None
|
|
670
595
|
with _DB.conn:
|
|
671
596
|
cursor = _DB.conn.cursor()
|
|
672
|
-
cursor.execute(
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
async def _add_or_update_request_no_lock_async(request: Request):
|
|
676
|
-
"""Async version of _add_or_update_request_no_lock."""
|
|
677
|
-
assert _DB is not None
|
|
678
|
-
conn = await _DB.async_conn()
|
|
679
|
-
await conn.execute(_add_or_update_request_sql, request.to_row())
|
|
680
|
-
await conn.commit()
|
|
597
|
+
cursor.execute(
|
|
598
|
+
f'INSERT OR REPLACE INTO {REQUEST_TABLE} ({key_str}) '
|
|
599
|
+
f'VALUES ({fill_str})', row)
|
|
681
600
|
|
|
682
601
|
|
|
683
602
|
def set_request_failed(request_id: str, e: BaseException) -> None:
|
sky/server/server.py
CHANGED
|
@@ -1397,7 +1397,7 @@ async def local_down(request: fastapi.Request) -> None:
|
|
|
1397
1397
|
async def api_get(request_id: str) -> payloads.RequestPayload:
|
|
1398
1398
|
"""Gets a request with a given request ID prefix."""
|
|
1399
1399
|
while True:
|
|
1400
|
-
request_task =
|
|
1400
|
+
request_task = requests_lib.get_request(request_id)
|
|
1401
1401
|
if request_task is None:
|
|
1402
1402
|
print(f'No task with request ID {request_id}', flush=True)
|
|
1403
1403
|
raise fastapi.HTTPException(
|
|
@@ -1486,7 +1486,7 @@ async def stream(
|
|
|
1486
1486
|
|
|
1487
1487
|
# Original plain text streaming logic
|
|
1488
1488
|
if request_id is not None:
|
|
1489
|
-
request_task =
|
|
1489
|
+
request_task = requests_lib.get_request(request_id)
|
|
1490
1490
|
if request_task is None:
|
|
1491
1491
|
print(f'No task with request ID {request_id}')
|
|
1492
1492
|
raise fastapi.HTTPException(
|
|
@@ -1581,7 +1581,7 @@ async def api_status(
|
|
|
1581
1581
|
else:
|
|
1582
1582
|
encoded_request_tasks = []
|
|
1583
1583
|
for request_id in request_ids:
|
|
1584
|
-
request_task =
|
|
1584
|
+
request_task = requests_lib.get_request(request_id)
|
|
1585
1585
|
if request_task is None:
|
|
1586
1586
|
continue
|
|
1587
1587
|
encoded_request_tasks.append(request_task.readable_encode())
|
|
@@ -1791,7 +1791,7 @@ async def complete_volume_name(incomplete: str,) -> List[str]:
|
|
|
1791
1791
|
|
|
1792
1792
|
@app.get('/api/completion/api_request')
|
|
1793
1793
|
async def complete_api_request(incomplete: str,) -> List[str]:
|
|
1794
|
-
return
|
|
1794
|
+
return requests_lib.get_api_request_ids_start_with(incomplete)
|
|
1795
1795
|
|
|
1796
1796
|
|
|
1797
1797
|
@app.get('/dashboard/{full_path:path}')
|
sky/server/stream_utils.py
CHANGED
|
@@ -56,7 +56,7 @@ async def log_streamer(request_id: Optional[str],
|
|
|
56
56
|
if request_id is not None:
|
|
57
57
|
status_msg = rich_utils.EncodedStatusMessage(
|
|
58
58
|
f'[dim]Checking request: {request_id}[/dim]')
|
|
59
|
-
request_task =
|
|
59
|
+
request_task = requests_lib.get_request(request_id)
|
|
60
60
|
|
|
61
61
|
if request_task is None:
|
|
62
62
|
raise fastapi.HTTPException(
|
|
@@ -86,12 +86,10 @@ async def log_streamer(request_id: Optional[str],
|
|
|
86
86
|
# Use smaller padding (1024 bytes) to force browser rendering
|
|
87
87
|
yield f'{waiting_msg}' + ' ' * 4096 + '\n'
|
|
88
88
|
# Sleep shortly to avoid storming the DB and CPU and allow other
|
|
89
|
-
# coroutines to run.
|
|
90
|
-
#
|
|
91
|
-
# polling the DB, which can be a bottleneck for high-concurrency
|
|
92
|
-
# requests.
|
|
89
|
+
# coroutines to run. This busy waiting loop is performance critical
|
|
90
|
+
# for short-running requests, so we do not want to yield too long.
|
|
93
91
|
await asyncio.sleep(0.1)
|
|
94
|
-
request_task =
|
|
92
|
+
request_task = requests_lib.get_request(request_id)
|
|
95
93
|
if not follow:
|
|
96
94
|
break
|
|
97
95
|
if show_request_waiting_spinner:
|
|
@@ -153,7 +151,7 @@ async def _tail_log_file(f: aiofiles.threadpool.binary.AsyncBufferedReader,
|
|
|
153
151
|
line: Optional[bytes] = await f.readline()
|
|
154
152
|
if not line:
|
|
155
153
|
if request_id is not None:
|
|
156
|
-
request_task =
|
|
154
|
+
request_task = requests_lib.get_request(request_id)
|
|
157
155
|
if request_task.status > requests_lib.RequestStatus.RUNNING:
|
|
158
156
|
if (request_task.status ==
|
|
159
157
|
requests_lib.RequestStatus.CANCELLED):
|
sky/setup_files/dependencies.py
CHANGED
|
@@ -8,8 +8,12 @@ This file is imported by setup.py, so:
|
|
|
8
8
|
import sys
|
|
9
9
|
from typing import Dict, List
|
|
10
10
|
|
|
11
|
+
clouds_with_ray = ['ibm', 'docker', 'scp']
|
|
12
|
+
|
|
11
13
|
install_requires = [
|
|
12
14
|
'wheel<0.46.0', # https://github.com/skypilot-org/skypilot/issues/5153
|
|
15
|
+
'setuptools', # TODO: match version to pyproject.toml once #5153 is fixed
|
|
16
|
+
'pip',
|
|
13
17
|
'cachetools',
|
|
14
18
|
# NOTE: ray requires click>=7.0.
|
|
15
19
|
# click 8.2.0 has a bug in parsing the command line arguments:
|
|
@@ -35,8 +39,7 @@ install_requires = [
|
|
|
35
39
|
# Light weight requirement, can be replaced with "typing" once
|
|
36
40
|
# we deprecate Python 3.7 (this will take a while).
|
|
37
41
|
'typing_extensions',
|
|
38
|
-
|
|
39
|
-
'filelock >= 3.15.0',
|
|
42
|
+
'filelock >= 3.6.0',
|
|
40
43
|
'packaging',
|
|
41
44
|
'psutil',
|
|
42
45
|
'pulp',
|
|
@@ -72,7 +75,6 @@ install_requires = [
|
|
|
72
75
|
'types-paramiko',
|
|
73
76
|
'alembic',
|
|
74
77
|
'aiohttp',
|
|
75
|
-
'aiosqlite',
|
|
76
78
|
'anyio',
|
|
77
79
|
]
|
|
78
80
|
|
|
@@ -98,7 +100,6 @@ server_dependencies = [
|
|
|
98
100
|
'anyio',
|
|
99
101
|
GRPC,
|
|
100
102
|
PROTOBUF,
|
|
101
|
-
'aiosqlite',
|
|
102
103
|
]
|
|
103
104
|
|
|
104
105
|
local_ray = [
|
|
@@ -148,7 +149,7 @@ extras_require: Dict[str, List[str]] = {
|
|
|
148
149
|
'azure-storage-blob>=12.23.1',
|
|
149
150
|
'msgraph-sdk',
|
|
150
151
|
'msrestazure',
|
|
151
|
-
]
|
|
152
|
+
],
|
|
152
153
|
# We need google-api-python-client>=2.69.0 to enable 'discardLocalSsd'
|
|
153
154
|
# parameter for stopping instances. Reference:
|
|
154
155
|
# https://github.com/googleapis/google-api-python-client/commit/f6e9d3869ed605b06f7cbf2e8cf2db25108506e6
|
|
@@ -169,7 +170,7 @@ extras_require: Dict[str, List[str]] = {
|
|
|
169
170
|
'lambda': [], # No dependencies needed for lambda
|
|
170
171
|
'cloudflare': aws_dependencies,
|
|
171
172
|
'scp': local_ray,
|
|
172
|
-
'oci': ['oci']
|
|
173
|
+
'oci': ['oci'],
|
|
173
174
|
# Kubernetes 32.0.0 has an authentication bug: https://github.com/kubernetes-client/python/issues/2333 # pylint: disable=line-too-long
|
|
174
175
|
'kubernetes': [
|
|
175
176
|
'kubernetes>=20.0.0,!=32.0.0', 'websockets', 'python-dateutil'
|
|
@@ -200,10 +201,21 @@ extras_require: Dict[str, List[str]] = {
|
|
|
200
201
|
'server': server_dependencies,
|
|
201
202
|
}
|
|
202
203
|
|
|
203
|
-
#
|
|
204
|
+
# Calculate which clouds should be included in the [all] installation.
|
|
205
|
+
clouds_for_all = set(extras_require)
|
|
206
|
+
clouds_for_all.remove('remote')
|
|
207
|
+
|
|
204
208
|
if sys.version_info < (3, 10):
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
209
|
+
# Nebius needs python3.10. If python 3.9 [all] will not install nebius
|
|
210
|
+
clouds_for_all.remove('nebius')
|
|
211
|
+
|
|
212
|
+
if sys.version_info >= (3, 12):
|
|
213
|
+
# The version of ray we use does not work with >= 3.12, so avoid clouds
|
|
214
|
+
# that require ray.
|
|
215
|
+
clouds_for_all -= set(clouds_with_ray)
|
|
216
|
+
# vast requires setuptools==51.1.1 which will not work with python >= 3.12
|
|
217
|
+
# TODO: Remove once https://github.com/vast-ai/vast-sdk/pull/6 is released
|
|
218
|
+
clouds_for_all.remove('vast')
|
|
219
|
+
|
|
220
|
+
extras_require['all'] = list(
|
|
221
|
+
set().union(*[extras_require[cloud] for cloud in clouds_for_all]))
|