skypilot-nightly 1.0.0.dev20250806__py3-none-any.whl → 1.0.0.dev20250807__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/cloud_vm_ray_backend.py +33 -4
- sky/check.py +11 -1
- sky/client/cli/command.py +208 -93
- sky/client/sdk.py +14 -1
- sky/client/sdk_async.py +4 -0
- sky/dashboard/out/404.html +1 -1
- sky/dashboard/out/_next/static/YAirOGsV1z6B2RJ0VIUmD/_buildManifest.js +1 -0
- sky/dashboard/out/_next/static/chunks/1141-a8a8f1adba34c892.js +11 -0
- sky/dashboard/out/_next/static/chunks/1871-980a395e92633a5c.js +6 -0
- sky/dashboard/out/_next/static/chunks/3785.6003d293cb83eab4.js +1 -0
- sky/dashboard/out/_next/static/chunks/3850-ff4a9a69d978632b.js +1 -0
- sky/dashboard/out/_next/static/chunks/4725.29550342bd53afd8.js +1 -0
- sky/dashboard/out/_next/static/chunks/{4937.d6bf67771e353356.js → 4937.a2baa2df5572a276.js} +1 -1
- sky/dashboard/out/_next/static/chunks/6130-2be46d70a38f1e82.js +1 -0
- sky/dashboard/out/_next/static/chunks/6601-3e21152fe16da09c.js +1 -0
- sky/dashboard/out/_next/static/chunks/{691.6d99cbfba347cebf.js → 691.5eeedf82cc243343.js} +1 -1
- sky/dashboard/out/_next/static/chunks/6989-6129c1cfbcf51063.js +1 -0
- sky/dashboard/out/_next/static/chunks/6990-0f886f16e0d55ff8.js +1 -0
- sky/dashboard/out/_next/static/chunks/8056-019615038d6ce427.js +1 -0
- sky/dashboard/out/_next/static/chunks/8252.62b0d23aed618bb2.js +16 -0
- sky/dashboard/out/_next/static/chunks/8969-318c3dca725e8e5d.js +1 -0
- sky/dashboard/out/_next/static/chunks/9025.a1bef12d672bb66d.js +6 -0
- sky/dashboard/out/_next/static/chunks/9159-11421c0f2909236f.js +1 -0
- sky/dashboard/out/_next/static/chunks/9360.85b0b1b4054574dd.js +31 -0
- sky/dashboard/out/_next/static/chunks/9666.cd4273f2a5c5802c.js +1 -0
- sky/dashboard/out/_next/static/chunks/{9847.4c46c5e229c78704.js → 9847.757720f3b40c0aa5.js} +1 -1
- sky/dashboard/out/_next/static/chunks/pages/{_app-2a43ea3241bbdacd.js → _app-1e6de35d15a8d432.js} +1 -1
- sky/dashboard/out/_next/static/chunks/pages/clusters/[cluster]/[job]-6fd1d2d8441aa54b.js +11 -0
- sky/dashboard/out/_next/static/chunks/pages/clusters/[cluster]-155d477a6c3e04e2.js +1 -0
- sky/dashboard/out/_next/static/chunks/pages/{clusters-47f1ddae13a2f8e4.js → clusters-b30460f683e6ba96.js} +1 -1
- sky/dashboard/out/_next/static/chunks/pages/config-dfb9bf07b13045f4.js +1 -0
- sky/dashboard/out/_next/static/chunks/pages/infra/{[context]-2a44e70b500b6b70.js → [context]-13d53fffc03ccb52.js} +1 -1
- sky/dashboard/out/_next/static/chunks/pages/{infra-22faac9325016d83.js → infra-fc9222e26c8e2f0d.js} +1 -1
- sky/dashboard/out/_next/static/chunks/pages/jobs/[job]-154f55cf8af55be5.js +11 -0
- sky/dashboard/out/_next/static/chunks/pages/jobs/pools/[pool]-f5ccf5d39d87aebe.js +21 -0
- sky/dashboard/out/_next/static/chunks/pages/jobs-cdc60fb5d371e16a.js +1 -0
- sky/dashboard/out/_next/static/chunks/pages/{users-b90c865a690bfe84.js → users-7ed36e44e779d5c7.js} +1 -1
- sky/dashboard/out/_next/static/chunks/pages/{volumes-7af733f5d7b6ed1c.js → volumes-c9695d657f78b5dc.js} +1 -1
- sky/dashboard/out/_next/static/chunks/pages/workspace/new-3f88a1c7e86a3f86.js +1 -0
- sky/dashboard/out/_next/static/chunks/pages/workspaces/[name]-f72f73bcef9541dc.js +1 -0
- sky/dashboard/out/_next/static/chunks/pages/workspaces-8f67be60165724cc.js +1 -0
- sky/dashboard/out/_next/static/chunks/webpack-76efbdad99742559.js +1 -0
- sky/dashboard/out/_next/static/css/4614e06482d7309e.css +3 -0
- 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 -0
- 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/global_user_state.py +14 -2
- sky/jobs/__init__.py +2 -0
- sky/jobs/client/sdk.py +43 -2
- sky/jobs/server/core.py +48 -1
- sky/jobs/server/server.py +52 -3
- sky/jobs/state.py +5 -1
- sky/schemas/db/global_user_state/002_add_workspace_to_cluster_history.py +35 -0
- sky/schemas/db/spot_jobs/003_pool_hash.py +34 -0
- sky/serve/client/impl.py +85 -1
- sky/serve/client/sdk.py +16 -47
- sky/serve/constants.py +2 -1
- sky/serve/controller.py +4 -2
- sky/serve/serve_state.py +28 -5
- sky/serve/serve_utils.py +77 -46
- sky/serve/server/core.py +13 -197
- sky/serve/server/impl.py +239 -2
- sky/serve/service.py +8 -3
- sky/server/common.py +11 -4
- sky/server/constants.py +1 -1
- sky/server/requests/executor.py +5 -3
- sky/server/requests/payloads.py +19 -0
- sky/task.py +18 -11
- sky/templates/kubernetes-ray.yml.j2 +5 -0
- sky/templates/sky-serve-controller.yaml.j2 +1 -0
- sky/usage/usage_lib.py +8 -6
- sky/utils/annotations.py +8 -3
- sky/utils/common_utils.py +11 -1
- sky/utils/db/migration_utils.py +2 -2
- {skypilot_nightly-1.0.0.dev20250806.dist-info → skypilot_nightly-1.0.0.dev20250807.dist-info}/METADATA +18 -13
- {skypilot_nightly-1.0.0.dev20250806.dist-info → skypilot_nightly-1.0.0.dev20250807.dist-info}/RECORD +95 -92
- sky/client/sdk.pyi +0 -301
- sky/dashboard/out/_next/static/Gelsd19kVxXcX7aQQGsGu/_buildManifest.js +0 -1
- sky/dashboard/out/_next/static/chunks/1043-75af48ca5d5aaf57.js +0 -1
- sky/dashboard/out/_next/static/chunks/1141-8678a9102cc5f67e.js +0 -11
- sky/dashboard/out/_next/static/chunks/1664-22b00e32c9ff96a4.js +0 -1
- sky/dashboard/out/_next/static/chunks/1871-ced1c14230cad6e1.js +0 -6
- sky/dashboard/out/_next/static/chunks/2003.f90b06bb1f914295.js +0 -1
- sky/dashboard/out/_next/static/chunks/2350.fab69e61bac57b23.js +0 -1
- sky/dashboard/out/_next/static/chunks/2622-951867535095b0eb.js +0 -1
- sky/dashboard/out/_next/static/chunks/3785.0a173cd4393f0fef.js +0 -1
- sky/dashboard/out/_next/static/chunks/4725.42f21f250f91f65b.js +0 -1
- sky/dashboard/out/_next/static/chunks/4869.18e6a4361a380763.js +0 -16
- sky/dashboard/out/_next/static/chunks/5230-f3bb2663e442e86c.js +0 -1
- sky/dashboard/out/_next/static/chunks/6601-2109d22e7861861c.js +0 -1
- sky/dashboard/out/_next/static/chunks/6990-08b2a1cae076a943.js +0 -1
- sky/dashboard/out/_next/static/chunks/8969-9a8cca241b30db83.js +0 -1
- sky/dashboard/out/_next/static/chunks/9025.99f29acb7617963e.js +0 -6
- sky/dashboard/out/_next/static/chunks/938-bda2685db5eae6cf.js +0 -1
- sky/dashboard/out/_next/static/chunks/pages/clusters/[cluster]/[job]-7cb24da04ca00956.js +0 -11
- sky/dashboard/out/_next/static/chunks/pages/clusters/[cluster]-1e95993124dbfc57.js +0 -1
- sky/dashboard/out/_next/static/chunks/pages/config-d56e64f30db7b42e.js +0 -1
- sky/dashboard/out/_next/static/chunks/pages/jobs/[job]-90693cb88b5599a7.js +0 -11
- sky/dashboard/out/_next/static/chunks/pages/jobs-ab318e52eb4424a7.js +0 -1
- sky/dashboard/out/_next/static/chunks/pages/workspace/new-92f741084a89e27b.js +0 -1
- sky/dashboard/out/_next/static/chunks/pages/workspaces/[name]-35e0de5bca55e594.js +0 -1
- sky/dashboard/out/_next/static/chunks/pages/workspaces-062525fb5462acb6.js +0 -1
- sky/dashboard/out/_next/static/chunks/webpack-387626669badf82e.js +0 -1
- sky/dashboard/out/_next/static/css/b3227360726f12eb.css +0 -3
- /sky/dashboard/out/_next/static/{Gelsd19kVxXcX7aQQGsGu → YAirOGsV1z6B2RJ0VIUmD}/_ssgManifest.js +0 -0
- /sky/dashboard/out/_next/static/chunks/{6135-2d7ed3350659d073.js → 6135-85426374db04811e.js} +0 -0
- {skypilot_nightly-1.0.0.dev20250806.dist-info → skypilot_nightly-1.0.0.dev20250807.dist-info}/WHEEL +0 -0
- {skypilot_nightly-1.0.0.dev20250806.dist-info → skypilot_nightly-1.0.0.dev20250807.dist-info}/entry_points.txt +0 -0
- {skypilot_nightly-1.0.0.dev20250806.dist-info → skypilot_nightly-1.0.0.dev20250807.dist-info}/licenses/LICENSE +0 -0
- {skypilot_nightly-1.0.0.dev20250806.dist-info → skypilot_nightly-1.0.0.dev20250807.dist-info}/top_level.txt +0 -0
|
@@ -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/
|
|
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-76efbdad99742559.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-1e6de35d15a8d432.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/6212-7bd06f60ba693125.js" defer=""></script><script src="/dashboard/_next/static/chunks/6989-6129c1cfbcf51063.js" defer=""></script><script src="/dashboard/_next/static/chunks/3850-ff4a9a69d978632b.js" defer=""></script><script src="/dashboard/_next/static/chunks/8969-318c3dca725e8e5d.js" defer=""></script><script src="/dashboard/_next/static/chunks/6135-85426374db04811e.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/jobs/%5Bjob%5D-154f55cf8af55be5.js" defer=""></script><script src="/dashboard/_next/static/YAirOGsV1z6B2RJ0VIUmD/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/YAirOGsV1z6B2RJ0VIUmD/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/jobs/[job]","query":{},"buildId":"YAirOGsV1z6B2RJ0VIUmD","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
|
|
@@ -0,0 +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-76efbdad99742559.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-1e6de35d15a8d432.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/1272-1ef0bf0237faccdb.js" defer=""></script><script src="/dashboard/_next/static/chunks/6212-7bd06f60ba693125.js" defer=""></script><script src="/dashboard/_next/static/chunks/6989-6129c1cfbcf51063.js" defer=""></script><script src="/dashboard/_next/static/chunks/3850-ff4a9a69d978632b.js" defer=""></script><script src="/dashboard/_next/static/chunks/8969-318c3dca725e8e5d.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/jobs/pools/%5Bpool%5D-f5ccf5d39d87aebe.js" defer=""></script><script src="/dashboard/_next/static/YAirOGsV1z6B2RJ0VIUmD/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/YAirOGsV1z6B2RJ0VIUmD/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/jobs/pools/[pool]","query":{},"buildId":"YAirOGsV1z6B2RJ0VIUmD","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
|
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/
|
|
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-76efbdad99742559.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-1e6de35d15a8d432.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/jobs-cdc60fb5d371e16a.js" defer=""></script><script src="/dashboard/_next/static/YAirOGsV1z6B2RJ0VIUmD/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/YAirOGsV1z6B2RJ0VIUmD/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/jobs","query":{},"buildId":"YAirOGsV1z6B2RJ0VIUmD","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/
|
|
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-76efbdad99742559.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-1e6de35d15a8d432.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/users-7ed36e44e779d5c7.js" defer=""></script><script src="/dashboard/_next/static/YAirOGsV1z6B2RJ0VIUmD/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/YAirOGsV1z6B2RJ0VIUmD/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/users","query":{},"buildId":"YAirOGsV1z6B2RJ0VIUmD","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/
|
|
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-76efbdad99742559.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-1e6de35d15a8d432.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/volumes-c9695d657f78b5dc.js" defer=""></script><script src="/dashboard/_next/static/YAirOGsV1z6B2RJ0VIUmD/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/YAirOGsV1z6B2RJ0VIUmD/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/volumes","query":{},"buildId":"YAirOGsV1z6B2RJ0VIUmD","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/
|
|
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-76efbdad99742559.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-1e6de35d15a8d432.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/workspace/new-3f88a1c7e86a3f86.js" defer=""></script><script src="/dashboard/_next/static/YAirOGsV1z6B2RJ0VIUmD/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/YAirOGsV1z6B2RJ0VIUmD/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/workspace/new","query":{},"buildId":"YAirOGsV1z6B2RJ0VIUmD","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/
|
|
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-76efbdad99742559.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-1e6de35d15a8d432.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/1559-6c00e20454194859.js" defer=""></script><script src="/dashboard/_next/static/chunks/6989-6129c1cfbcf51063.js" defer=""></script><script src="/dashboard/_next/static/chunks/3850-ff4a9a69d978632b.js" defer=""></script><script src="/dashboard/_next/static/chunks/8969-318c3dca725e8e5d.js" defer=""></script><script src="/dashboard/_next/static/chunks/6990-0f886f16e0d55ff8.js" defer=""></script><script src="/dashboard/_next/static/chunks/8056-019615038d6ce427.js" defer=""></script><script src="/dashboard/_next/static/chunks/6135-85426374db04811e.js" defer=""></script><script src="/dashboard/_next/static/chunks/6601-3e21152fe16da09c.js" defer=""></script><script src="/dashboard/_next/static/chunks/9159-11421c0f2909236f.js" defer=""></script><script src="/dashboard/_next/static/chunks/1141-a8a8f1adba34c892.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/workspaces/%5Bname%5D-f72f73bcef9541dc.js" defer=""></script><script src="/dashboard/_next/static/YAirOGsV1z6B2RJ0VIUmD/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/YAirOGsV1z6B2RJ0VIUmD/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/workspaces/[name]","query":{},"buildId":"YAirOGsV1z6B2RJ0VIUmD","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/
|
|
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-76efbdad99742559.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-1e6de35d15a8d432.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/workspaces-8f67be60165724cc.js" defer=""></script><script src="/dashboard/_next/static/YAirOGsV1z6B2RJ0VIUmD/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/YAirOGsV1z6B2RJ0VIUmD/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/workspaces","query":{},"buildId":"YAirOGsV1z6B2RJ0VIUmD","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
|
sky/global_user_state.py
CHANGED
|
@@ -158,6 +158,7 @@ cluster_history_table = sqlalchemy.Table(
|
|
|
158
158
|
sqlalchemy.Column('last_creation_command',
|
|
159
159
|
sqlalchemy.Text,
|
|
160
160
|
server_default=None),
|
|
161
|
+
sqlalchemy.Column('workspace', sqlalchemy.Text, server_default=None),
|
|
161
162
|
)
|
|
162
163
|
|
|
163
164
|
ssh_key_table = sqlalchemy.Table(
|
|
@@ -476,6 +477,8 @@ def add_or_update_cluster(cluster_name: str,
|
|
|
476
477
|
|
|
477
478
|
user_hash = common_utils.get_current_user().id
|
|
478
479
|
active_workspace = skypilot_config.get_active_workspace()
|
|
480
|
+
history_workspace = active_workspace
|
|
481
|
+
history_hash = user_hash
|
|
479
482
|
|
|
480
483
|
conditional_values = {}
|
|
481
484
|
if is_launch:
|
|
@@ -560,6 +563,10 @@ def add_or_update_cluster(cluster_name: str,
|
|
|
560
563
|
# Modify cluster history table
|
|
561
564
|
launched_nodes = getattr(cluster_handle, 'launched_nodes', None)
|
|
562
565
|
launched_resources = getattr(cluster_handle, 'launched_resources', None)
|
|
566
|
+
if cluster_row and cluster_row.workspace:
|
|
567
|
+
history_workspace = cluster_row.workspace
|
|
568
|
+
if cluster_row and cluster_row.user_hash:
|
|
569
|
+
history_hash = cluster_row.user_hash
|
|
563
570
|
creation_info = {}
|
|
564
571
|
if conditional_values.get('last_creation_yaml') is not None:
|
|
565
572
|
creation_info = {
|
|
@@ -577,6 +584,7 @@ def add_or_update_cluster(cluster_name: str,
|
|
|
577
584
|
launched_resources=pickle.dumps(launched_resources),
|
|
578
585
|
usage_intervals=pickle.dumps(usage_intervals),
|
|
579
586
|
user_hash=user_hash,
|
|
587
|
+
workspace=history_workspace,
|
|
580
588
|
**creation_info,
|
|
581
589
|
)
|
|
582
590
|
do_update_stmt = insert_stmnt.on_conflict_do_update(
|
|
@@ -590,7 +598,8 @@ def add_or_update_cluster(cluster_name: str,
|
|
|
590
598
|
pickle.dumps(launched_resources),
|
|
591
599
|
cluster_history_table.c.usage_intervals:
|
|
592
600
|
pickle.dumps(usage_intervals),
|
|
593
|
-
cluster_history_table.c.user_hash:
|
|
601
|
+
cluster_history_table.c.user_hash: history_hash,
|
|
602
|
+
cluster_history_table.c.workspace: history_workspace,
|
|
594
603
|
**creation_info,
|
|
595
604
|
})
|
|
596
605
|
session.execute(do_update_stmt)
|
|
@@ -1026,6 +1035,7 @@ def get_clusters_from_history(
|
|
|
1026
1035
|
cluster_history_table.c.user_hash,
|
|
1027
1036
|
cluster_history_table.c.last_creation_yaml,
|
|
1028
1037
|
cluster_history_table.c.last_creation_command,
|
|
1038
|
+
cluster_history_table.c.workspace.label('history_workspace'),
|
|
1029
1039
|
cluster_table.c.status, cluster_table.c.workspace,
|
|
1030
1040
|
cluster_table.c.status_updated_at).select_from(
|
|
1031
1041
|
cluster_history_table.join(cluster_table,
|
|
@@ -1096,6 +1106,8 @@ def get_clusters_from_history(
|
|
|
1096
1106
|
# Get user name from user hash
|
|
1097
1107
|
user = get_user(user_hash)
|
|
1098
1108
|
user_name = user.name if user is not None else None
|
|
1109
|
+
workspace = (row.history_workspace
|
|
1110
|
+
if row.history_workspace else row.workspace)
|
|
1099
1111
|
|
|
1100
1112
|
record = {
|
|
1101
1113
|
'name': row.name,
|
|
@@ -1108,7 +1120,7 @@ def get_clusters_from_history(
|
|
|
1108
1120
|
'status': status,
|
|
1109
1121
|
'user_hash': user_hash,
|
|
1110
1122
|
'user_name': user_name,
|
|
1111
|
-
'workspace':
|
|
1123
|
+
'workspace': workspace,
|
|
1112
1124
|
'last_creation_yaml': row.last_creation_yaml,
|
|
1113
1125
|
'last_creation_command': row.last_creation_command,
|
|
1114
1126
|
}
|
sky/jobs/__init__.py
CHANGED
|
@@ -8,6 +8,8 @@ from sky.jobs.client.sdk import launch
|
|
|
8
8
|
from sky.jobs.client.sdk import pool_apply
|
|
9
9
|
from sky.jobs.client.sdk import pool_down
|
|
10
10
|
from sky.jobs.client.sdk import pool_status
|
|
11
|
+
from sky.jobs.client.sdk import pool_sync_down_logs
|
|
12
|
+
from sky.jobs.client.sdk import pool_tail_logs
|
|
11
13
|
from sky.jobs.client.sdk import queue
|
|
12
14
|
from sky.jobs.client.sdk import tail_logs
|
|
13
15
|
from sky.jobs.constants import JOBS_CLUSTER_NAME_PREFIX_LENGTH
|
sky/jobs/client/sdk.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""SDK functions for managed jobs."""
|
|
2
2
|
import json
|
|
3
3
|
import typing
|
|
4
|
-
from typing import Dict, List, Optional, Union
|
|
4
|
+
from typing import Dict, List, Optional, Sequence, Union
|
|
5
5
|
|
|
6
6
|
import click
|
|
7
7
|
|
|
@@ -186,7 +186,7 @@ def queue(refresh: bool,
|
|
|
186
186
|
@server_common.check_server_healthy_or_start
|
|
187
187
|
def cancel(
|
|
188
188
|
name: Optional[str] = None,
|
|
189
|
-
job_ids: Optional[
|
|
189
|
+
job_ids: Optional[Sequence[int]] = None,
|
|
190
190
|
all: bool = False, # pylint: disable=redefined-builtin
|
|
191
191
|
all_users: bool = False,
|
|
192
192
|
pool: Optional[str] = None,
|
|
@@ -408,3 +408,44 @@ def pool_status(
|
|
|
408
408
|
pool_names: Optional[Union[str, List[str]]],) -> server_common.RequestId:
|
|
409
409
|
"""Query a pool."""
|
|
410
410
|
return impl.status(pool_names, pool=True)
|
|
411
|
+
|
|
412
|
+
|
|
413
|
+
@usage_lib.entrypoint
|
|
414
|
+
@server_common.check_server_healthy_or_start
|
|
415
|
+
@rest.retry_transient_errors()
|
|
416
|
+
@versions.minimal_api_version(13)
|
|
417
|
+
def pool_tail_logs(pool_name: str,
|
|
418
|
+
target: Union[str, 'serve_utils.ServiceComponent'],
|
|
419
|
+
worker_id: Optional[int] = None,
|
|
420
|
+
follow: bool = True,
|
|
421
|
+
output_stream: Optional['io.TextIOBase'] = None,
|
|
422
|
+
tail: Optional[int] = None) -> None:
|
|
423
|
+
"""Tails logs of a pool."""
|
|
424
|
+
return impl.tail_logs(pool_name,
|
|
425
|
+
target,
|
|
426
|
+
worker_id,
|
|
427
|
+
follow,
|
|
428
|
+
output_stream,
|
|
429
|
+
tail,
|
|
430
|
+
pool=True)
|
|
431
|
+
|
|
432
|
+
|
|
433
|
+
@usage_lib.entrypoint
|
|
434
|
+
@server_common.check_server_healthy_or_start
|
|
435
|
+
@rest.retry_transient_errors()
|
|
436
|
+
@versions.minimal_api_version(13)
|
|
437
|
+
def pool_sync_down_logs(pool_name: str,
|
|
438
|
+
local_dir: str,
|
|
439
|
+
*,
|
|
440
|
+
targets: Optional[Union[
|
|
441
|
+
str, 'serve_utils.ServiceComponent', Sequence[Union[
|
|
442
|
+
str, 'serve_utils.ServiceComponent']]]] = None,
|
|
443
|
+
worker_ids: Optional[List[int]] = None,
|
|
444
|
+
tail: Optional[int] = None) -> None:
|
|
445
|
+
"""Sync down logs of a pool."""
|
|
446
|
+
return impl.sync_down_logs(pool_name,
|
|
447
|
+
local_dir,
|
|
448
|
+
targets=targets,
|
|
449
|
+
replica_ids=worker_ids,
|
|
450
|
+
tail=tail,
|
|
451
|
+
pool=True)
|
sky/jobs/server/core.py
CHANGED
|
@@ -24,6 +24,7 @@ from sky.jobs import constants as managed_job_constants
|
|
|
24
24
|
from sky.jobs import state as managed_job_state
|
|
25
25
|
from sky.jobs import utils as managed_job_utils
|
|
26
26
|
from sky.provision import common as provision_common
|
|
27
|
+
from sky.serve import serve_state
|
|
27
28
|
from sky.serve import serve_utils
|
|
28
29
|
from sky.serve.server import impl
|
|
29
30
|
from sky.skylet import constants as skylet_constants
|
|
@@ -108,6 +109,11 @@ def _maybe_submit_job_locally(prefix: str, dag: 'sky.Dag', pool: Optional[str],
|
|
|
108
109
|
# Create local directory for the managed job.
|
|
109
110
|
pathlib.Path(prefix).expanduser().mkdir(parents=True, exist_ok=True)
|
|
110
111
|
job_ids = []
|
|
112
|
+
pool_hash = None
|
|
113
|
+
if pool is not None:
|
|
114
|
+
pool_hash = serve_state.get_service_hash(pool)
|
|
115
|
+
# Already checked in the sdk.
|
|
116
|
+
assert pool_hash is not None, f'Pool {pool} not found'
|
|
111
117
|
for _ in range(num_jobs if num_jobs is not None else 1):
|
|
112
118
|
# TODO(tian): We should have a separate name for each job when
|
|
113
119
|
# submitting multiple jobs. Current blocker is that we are sharing
|
|
@@ -121,7 +127,8 @@ def _maybe_submit_job_locally(prefix: str, dag: 'sky.Dag', pool: Optional[str],
|
|
|
121
127
|
workspace=skypilot_config.get_active_workspace(
|
|
122
128
|
force_user_workspace=True),
|
|
123
129
|
entrypoint=common_utils.get_current_command(),
|
|
124
|
-
pool=pool
|
|
130
|
+
pool=pool,
|
|
131
|
+
pool_hash=pool_hash))
|
|
125
132
|
for task_id, task in enumerate(dag.tasks):
|
|
126
133
|
resources_str = backend_utils.get_task_resources_str(
|
|
127
134
|
task, is_managed_job=True)
|
|
@@ -843,3 +850,43 @@ def pool_status(
|
|
|
843
850
|
List[str]]] = None,) -> List[Dict[str, Any]]:
|
|
844
851
|
"""Query a pool."""
|
|
845
852
|
return impl.status(pool_names, pool=True)
|
|
853
|
+
|
|
854
|
+
|
|
855
|
+
ServiceComponentOrStr = Union[str, serve_utils.ServiceComponent]
|
|
856
|
+
|
|
857
|
+
|
|
858
|
+
@usage_lib.entrypoint
|
|
859
|
+
def pool_tail_logs(
|
|
860
|
+
pool_name: str,
|
|
861
|
+
*,
|
|
862
|
+
target: ServiceComponentOrStr,
|
|
863
|
+
worker_id: Optional[int] = None,
|
|
864
|
+
follow: bool = True,
|
|
865
|
+
tail: Optional[int] = None,
|
|
866
|
+
) -> None:
|
|
867
|
+
"""Tail logs of a pool."""
|
|
868
|
+
return impl.tail_logs(pool_name,
|
|
869
|
+
target=target,
|
|
870
|
+
replica_id=worker_id,
|
|
871
|
+
follow=follow,
|
|
872
|
+
tail=tail,
|
|
873
|
+
pool=True)
|
|
874
|
+
|
|
875
|
+
|
|
876
|
+
@usage_lib.entrypoint
|
|
877
|
+
def pool_sync_down_logs(
|
|
878
|
+
pool_name: str,
|
|
879
|
+
*,
|
|
880
|
+
local_dir: str,
|
|
881
|
+
targets: Union[ServiceComponentOrStr, List[ServiceComponentOrStr],
|
|
882
|
+
None] = None,
|
|
883
|
+
worker_ids: Optional[List[int]] = None,
|
|
884
|
+
tail: Optional[int] = None,
|
|
885
|
+
) -> str:
|
|
886
|
+
"""Sync down logs of a pool."""
|
|
887
|
+
return impl.sync_down_logs(pool_name,
|
|
888
|
+
local_dir=local_dir,
|
|
889
|
+
targets=targets,
|
|
890
|
+
replica_ids=worker_ids,
|
|
891
|
+
tail=tail,
|
|
892
|
+
pool=True)
|
sky/jobs/server/server.py
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
"""REST API for managed jobs."""
|
|
2
2
|
|
|
3
|
+
import pathlib
|
|
4
|
+
|
|
3
5
|
import fastapi
|
|
4
6
|
|
|
5
7
|
from sky import sky_logging
|
|
@@ -117,7 +119,7 @@ async def pool_apply(request: fastapi.Request,
|
|
|
117
119
|
request_body=jobs_pool_apply_body,
|
|
118
120
|
func=core.pool_apply,
|
|
119
121
|
schedule_type=api_requests.ScheduleType.LONG,
|
|
120
|
-
request_cluster_name=common.
|
|
122
|
+
request_cluster_name=common.JOB_CONTROLLER_NAME,
|
|
121
123
|
)
|
|
122
124
|
|
|
123
125
|
|
|
@@ -130,7 +132,7 @@ async def pool_down(request: fastapi.Request,
|
|
|
130
132
|
request_body=jobs_pool_down_body,
|
|
131
133
|
func=core.pool_down,
|
|
132
134
|
schedule_type=api_requests.ScheduleType.SHORT,
|
|
133
|
-
request_cluster_name=common.
|
|
135
|
+
request_cluster_name=common.JOB_CONTROLLER_NAME,
|
|
134
136
|
)
|
|
135
137
|
|
|
136
138
|
|
|
@@ -144,5 +146,52 @@ async def pool_status(
|
|
|
144
146
|
request_body=jobs_pool_status_body,
|
|
145
147
|
func=core.pool_status,
|
|
146
148
|
schedule_type=api_requests.ScheduleType.SHORT,
|
|
147
|
-
request_cluster_name=common.
|
|
149
|
+
request_cluster_name=common.JOB_CONTROLLER_NAME,
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
@router.post('/pool_logs')
|
|
154
|
+
async def pool_tail_logs(
|
|
155
|
+
request: fastapi.Request, log_body: payloads.JobsPoolLogsBody,
|
|
156
|
+
background_tasks: fastapi.BackgroundTasks
|
|
157
|
+
) -> fastapi.responses.StreamingResponse:
|
|
158
|
+
executor.schedule_request(
|
|
159
|
+
request_id=request.state.request_id,
|
|
160
|
+
request_name='jobs.pool_logs',
|
|
161
|
+
request_body=log_body,
|
|
162
|
+
func=core.pool_tail_logs,
|
|
163
|
+
schedule_type=api_requests.ScheduleType.SHORT,
|
|
164
|
+
request_cluster_name=common.JOB_CONTROLLER_NAME,
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
request_task = api_requests.get_request(request.state.request_id)
|
|
168
|
+
|
|
169
|
+
return stream_utils.stream_response(
|
|
170
|
+
request_id=request_task.request_id,
|
|
171
|
+
logs_path=request_task.log_path,
|
|
172
|
+
background_tasks=background_tasks,
|
|
173
|
+
)
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
@router.post('/pool_sync-down-logs')
|
|
177
|
+
async def pool_download_logs(
|
|
178
|
+
request: fastapi.Request,
|
|
179
|
+
download_logs_body: payloads.JobsPoolDownloadLogsBody,
|
|
180
|
+
) -> None:
|
|
181
|
+
user_hash = download_logs_body.env_vars[constants.USER_ID_ENV_VAR]
|
|
182
|
+
timestamp = sky_logging.get_run_timestamp()
|
|
183
|
+
logs_dir_on_api_server = (
|
|
184
|
+
pathlib.Path(server_common.api_server_user_logs_dir_prefix(user_hash)) /
|
|
185
|
+
'pool' / f'{download_logs_body.pool_name}_{timestamp}')
|
|
186
|
+
logs_dir_on_api_server.mkdir(parents=True, exist_ok=True)
|
|
187
|
+
# We should reuse the original request body, so that the env vars, such as
|
|
188
|
+
# user hash, are kept the same.
|
|
189
|
+
download_logs_body.local_dir = str(logs_dir_on_api_server)
|
|
190
|
+
executor.schedule_request(
|
|
191
|
+
request_id=request.state.request_id,
|
|
192
|
+
request_name='jobs.pool_sync_down_logs',
|
|
193
|
+
request_body=download_logs_body,
|
|
194
|
+
func=core.pool_sync_down_logs,
|
|
195
|
+
schedule_type=api_requests.ScheduleType.SHORT,
|
|
196
|
+
request_cluster_name=common.JOB_CONTROLLER_NAME,
|
|
148
197
|
)
|
sky/jobs/state.py
CHANGED
|
@@ -107,6 +107,7 @@ job_info_table = sqlalchemy.Table(
|
|
|
107
107
|
sqlalchemy.Column('job_id_on_pool_cluster',
|
|
108
108
|
sqlalchemy.Integer,
|
|
109
109
|
server_default=None),
|
|
110
|
+
sqlalchemy.Column('pool_hash', sqlalchemy.Text, server_default=None),
|
|
110
111
|
)
|
|
111
112
|
|
|
112
113
|
ha_recovery_script_table = sqlalchemy.Table(
|
|
@@ -225,6 +226,7 @@ def _get_jobs_dict(r: 'row.RowMapping') -> Dict[str, Any]:
|
|
|
225
226
|
'pool': r['pool'],
|
|
226
227
|
'current_cluster_name': r['current_cluster_name'],
|
|
227
228
|
'job_id_on_pool_cluster': r['job_id_on_pool_cluster'],
|
|
229
|
+
'pool_hash': r['pool_hash'],
|
|
228
230
|
}
|
|
229
231
|
|
|
230
232
|
|
|
@@ -462,7 +464,8 @@ def set_job_info(job_id: int, name: str, workspace: str, entrypoint: str):
|
|
|
462
464
|
|
|
463
465
|
@_init_db
|
|
464
466
|
def set_job_info_without_job_id(name: str, workspace: str, entrypoint: str,
|
|
465
|
-
pool: Optional[str]
|
|
467
|
+
pool: Optional[str],
|
|
468
|
+
pool_hash: Optional[str]) -> int:
|
|
466
469
|
assert _SQLALCHEMY_ENGINE is not None
|
|
467
470
|
with orm.Session(_SQLALCHEMY_ENGINE) as session:
|
|
468
471
|
if (_SQLALCHEMY_ENGINE.dialect.name ==
|
|
@@ -480,6 +483,7 @@ def set_job_info_without_job_id(name: str, workspace: str, entrypoint: str,
|
|
|
480
483
|
workspace=workspace,
|
|
481
484
|
entrypoint=entrypoint,
|
|
482
485
|
pool=pool,
|
|
486
|
+
pool_hash=pool_hash,
|
|
483
487
|
)
|
|
484
488
|
|
|
485
489
|
if (_SQLALCHEMY_ENGINE.dialect.name ==
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"""add workspace column to cluster_history table
|
|
2
|
+
|
|
3
|
+
Revision ID: 002
|
|
4
|
+
Revises: 001
|
|
5
|
+
Create Date: 2025-08-06
|
|
6
|
+
|
|
7
|
+
"""
|
|
8
|
+
# pylint: disable=invalid-name
|
|
9
|
+
from typing import Sequence, Union
|
|
10
|
+
|
|
11
|
+
from alembic import op
|
|
12
|
+
import sqlalchemy as sa
|
|
13
|
+
|
|
14
|
+
from sky.utils.db import db_utils
|
|
15
|
+
|
|
16
|
+
# revision identifiers, used by Alembic.
|
|
17
|
+
revision: str = '002'
|
|
18
|
+
down_revision: Union[str, Sequence[str], None] = '001'
|
|
19
|
+
branch_labels: Union[str, Sequence[str], None] = None
|
|
20
|
+
depends_on: Union[str, Sequence[str], None] = None
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def upgrade() -> None:
|
|
24
|
+
"""Upgrade schema."""
|
|
25
|
+
with op.get_context().autocommit_block():
|
|
26
|
+
db_utils.add_column_to_table_alembic('cluster_history',
|
|
27
|
+
'workspace',
|
|
28
|
+
sa.Text(),
|
|
29
|
+
server_default=None)
|
|
30
|
+
pass
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def downgrade() -> None:
|
|
34
|
+
"""Downgrade schema."""
|
|
35
|
+
pass
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"""Adding a hash column for pool.
|
|
2
|
+
|
|
3
|
+
Revision ID: 003
|
|
4
|
+
Revises: 002
|
|
5
|
+
Create Date: 2025-07-18
|
|
6
|
+
|
|
7
|
+
"""
|
|
8
|
+
# pylint: disable=invalid-name
|
|
9
|
+
from typing import Sequence, Union
|
|
10
|
+
|
|
11
|
+
from alembic import op
|
|
12
|
+
import sqlalchemy as sa
|
|
13
|
+
|
|
14
|
+
from sky.utils.db import db_utils
|
|
15
|
+
|
|
16
|
+
# revision identifiers, used by Alembic.
|
|
17
|
+
revision: str = '003'
|
|
18
|
+
down_revision: Union[str, Sequence[str], None] = '002'
|
|
19
|
+
branch_labels: Union[str, Sequence[str], None] = None
|
|
20
|
+
depends_on: Union[str, Sequence[str], None] = None
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def upgrade():
|
|
24
|
+
"""Add columns for pool hash."""
|
|
25
|
+
with op.get_context().autocommit_block():
|
|
26
|
+
db_utils.add_column_to_table_alembic('job_info',
|
|
27
|
+
'pool_hash',
|
|
28
|
+
sa.Text(),
|
|
29
|
+
server_default=None)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def downgrade():
|
|
33
|
+
"""Remove columns for pool hash."""
|
|
34
|
+
pass
|
sky/serve/client/impl.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""Implementation of SDK for SkyServe."""
|
|
2
2
|
import json
|
|
3
3
|
import typing
|
|
4
|
-
from typing import List, Optional, Union
|
|
4
|
+
from typing import List, Optional, Sequence, Union
|
|
5
5
|
|
|
6
6
|
import click
|
|
7
7
|
|
|
@@ -12,6 +12,8 @@ from sky.utils import admin_policy_utils
|
|
|
12
12
|
from sky.utils import dag_utils
|
|
13
13
|
|
|
14
14
|
if typing.TYPE_CHECKING:
|
|
15
|
+
import io
|
|
16
|
+
|
|
15
17
|
import sky
|
|
16
18
|
from sky.serve import serve_utils
|
|
17
19
|
|
|
@@ -186,3 +188,85 @@ def status(
|
|
|
186
188
|
json=json.loads(body.model_dump_json()),
|
|
187
189
|
timeout=(5, None))
|
|
188
190
|
return server_common.get_request_id(response)
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
def tail_logs(service_name: str,
|
|
194
|
+
target: Union[str, 'serve_utils.ServiceComponent'],
|
|
195
|
+
replica_id: Optional[int] = None,
|
|
196
|
+
follow: bool = True,
|
|
197
|
+
output_stream: Optional['io.TextIOBase'] = None,
|
|
198
|
+
tail: Optional[int] = None,
|
|
199
|
+
pool: bool = False) -> None:
|
|
200
|
+
# Avoid circular import.
|
|
201
|
+
from sky.client import sdk # pylint: disable=import-outside-toplevel
|
|
202
|
+
|
|
203
|
+
if pool:
|
|
204
|
+
body = payloads.JobsPoolLogsBody(
|
|
205
|
+
pool_name=service_name,
|
|
206
|
+
target=target,
|
|
207
|
+
worker_id=replica_id,
|
|
208
|
+
follow=follow,
|
|
209
|
+
tail=tail,
|
|
210
|
+
)
|
|
211
|
+
else:
|
|
212
|
+
body = payloads.ServeLogsBody(
|
|
213
|
+
service_name=service_name,
|
|
214
|
+
target=target,
|
|
215
|
+
replica_id=replica_id,
|
|
216
|
+
follow=follow,
|
|
217
|
+
tail=tail,
|
|
218
|
+
)
|
|
219
|
+
response = server_common.make_authenticated_request(
|
|
220
|
+
'POST',
|
|
221
|
+
'/jobs/pool_logs' if pool else '/serve/logs',
|
|
222
|
+
json=json.loads(body.model_dump_json()),
|
|
223
|
+
timeout=(5, None),
|
|
224
|
+
stream=True)
|
|
225
|
+
request_id = server_common.get_request_id(response)
|
|
226
|
+
return sdk.stream_response(request_id=request_id,
|
|
227
|
+
response=response,
|
|
228
|
+
output_stream=output_stream,
|
|
229
|
+
resumable=True)
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
def sync_down_logs(service_name: str,
|
|
233
|
+
local_dir: str,
|
|
234
|
+
*,
|
|
235
|
+
targets: Optional[Union[
|
|
236
|
+
str, 'serve_utils.ServiceComponent',
|
|
237
|
+
Sequence[Union[str,
|
|
238
|
+
'serve_utils.ServiceComponent']]]] = None,
|
|
239
|
+
replica_ids: Optional[List[int]] = None,
|
|
240
|
+
tail: Optional[int] = None,
|
|
241
|
+
pool: bool = False) -> None:
|
|
242
|
+
# Avoid circular import.
|
|
243
|
+
from sky.client import sdk # pylint: disable=import-outside-toplevel
|
|
244
|
+
|
|
245
|
+
if pool:
|
|
246
|
+
body = payloads.JobsPoolDownloadLogsBody(
|
|
247
|
+
pool_name=service_name,
|
|
248
|
+
local_dir=local_dir,
|
|
249
|
+
targets=targets,
|
|
250
|
+
worker_ids=replica_ids,
|
|
251
|
+
tail=tail,
|
|
252
|
+
)
|
|
253
|
+
else:
|
|
254
|
+
body = payloads.ServeDownloadLogsBody(
|
|
255
|
+
service_name=service_name,
|
|
256
|
+
# No need to set here, since the server will override it
|
|
257
|
+
# to a directory on the API server.
|
|
258
|
+
local_dir=local_dir,
|
|
259
|
+
targets=targets,
|
|
260
|
+
replica_ids=replica_ids,
|
|
261
|
+
tail=tail,
|
|
262
|
+
)
|
|
263
|
+
response = server_common.make_authenticated_request(
|
|
264
|
+
'POST',
|
|
265
|
+
'/jobs/pool_sync-down-logs' if pool else '/serve/sync-down-logs',
|
|
266
|
+
json=json.loads(body.model_dump_json()),
|
|
267
|
+
timeout=(5, None))
|
|
268
|
+
remote_dir = sdk.stream_and_get(server_common.get_request_id(response))
|
|
269
|
+
|
|
270
|
+
# Download from API server paths to the client's local_dir
|
|
271
|
+
client_common.download_logs_from_api_server([remote_dir], remote_dir,
|
|
272
|
+
local_dir)
|