skypilot-nightly 1.0.0.dev20250807__py3-none-any.whl → 1.0.0.dev20250808__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 +20 -1
- sky/backends/cloud_vm_ray_backend.py +9 -2
- sky/client/cli/command.py +40 -26
- sky/client/sdk.py +132 -65
- sky/client/sdk_async.py +1 -1
- sky/core.py +5 -2
- sky/dashboard/out/404.html +1 -1
- sky/dashboard/out/_next/static/{YAirOGsV1z6B2RJ0VIUmD → -DXZksWqf2waNHeU9YTQe}/_buildManifest.js +1 -1
- sky/dashboard/out/_next/static/chunks/{6601-3e21152fe16da09c.js → 6601-06114c982db410b6.js} +1 -1
- sky/dashboard/out/_next/static/chunks/8056-34d27f51e6d1c631.js +1 -0
- sky/dashboard/out/_next/static/chunks/{8969-318c3dca725e8e5d.js → 8969-c9686994ddafcf01.js} +1 -1
- sky/dashboard/out/_next/static/chunks/pages/{_app-1e6de35d15a8d432.js → _app-491a4d699d95e808.js} +1 -1
- sky/dashboard/out/_next/static/chunks/pages/clusters/[cluster]/[job]-ae17cec0fc6483d9.js +11 -0
- sky/dashboard/out/_next/static/chunks/webpack-339efec49c0cc7d0.js +1 -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 -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/execution.py +6 -4
- sky/global_user_state.py +8 -1
- sky/jobs/client/sdk.py +27 -20
- sky/jobs/controller.py +2 -1
- sky/schemas/db/global_user_state/003_fix_initial_revision.py +61 -0
- sky/schemas/db/global_user_state/004_is_managed.py +34 -0
- sky/schemas/db/serve_state/001_initial_schema.py +67 -0
- sky/serve/client/impl.py +11 -8
- sky/serve/client/sdk.py +7 -7
- sky/serve/serve_state.py +437 -340
- sky/serve/server/impl.py +2 -2
- sky/server/common.py +12 -8
- sky/server/constants.py +1 -1
- sky/setup_files/alembic.ini +4 -0
- sky/utils/cli_utils/status_utils.py +1 -1
- sky/utils/db/db_utils.py +31 -0
- sky/utils/db/migration_utils.py +5 -1
- sky/utils/kubernetes/deploy_remote_cluster.py +3 -1
- sky/utils/resource_checker.py +162 -21
- sky/volumes/client/sdk.py +4 -4
- sky/workspaces/core.py +210 -6
- {skypilot_nightly-1.0.0.dev20250807.dist-info → skypilot_nightly-1.0.0.dev20250808.dist-info}/METADATA +2 -2
- {skypilot_nightly-1.0.0.dev20250807.dist-info → skypilot_nightly-1.0.0.dev20250808.dist-info}/RECORD +58 -55
- sky/dashboard/out/_next/static/chunks/8056-019615038d6ce427.js +0 -1
- sky/dashboard/out/_next/static/chunks/pages/clusters/[cluster]/[job]-6fd1d2d8441aa54b.js +0 -11
- sky/dashboard/out/_next/static/chunks/webpack-76efbdad99742559.js +0 -1
- /sky/dashboard/out/_next/static/{YAirOGsV1z6B2RJ0VIUmD → -DXZksWqf2waNHeU9YTQe}/_ssgManifest.js +0 -0
- {skypilot_nightly-1.0.0.dev20250807.dist-info → skypilot_nightly-1.0.0.dev20250808.dist-info}/WHEEL +0 -0
- {skypilot_nightly-1.0.0.dev20250807.dist-info → skypilot_nightly-1.0.0.dev20250808.dist-info}/entry_points.txt +0 -0
- {skypilot_nightly-1.0.0.dev20250807.dist-info → skypilot_nightly-1.0.0.dev20250808.dist-info}/licenses/LICENSE +0 -0
- {skypilot_nightly-1.0.0.dev20250807.dist-info → skypilot_nightly-1.0.0.dev20250808.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/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-
|
|
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-339efec49c0cc7d0.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-491a4d699d95e808.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-c9686994ddafcf01.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/jobs/pools/%5Bpool%5D-f5ccf5d39d87aebe.js" defer=""></script><script src="/dashboard/_next/static/-DXZksWqf2waNHeU9YTQe/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/-DXZksWqf2waNHeU9YTQe/_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":"-DXZksWqf2waNHeU9YTQe","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/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-
|
|
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-339efec49c0cc7d0.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-491a4d699d95e808.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/jobs-cdc60fb5d371e16a.js" defer=""></script><script src="/dashboard/_next/static/-DXZksWqf2waNHeU9YTQe/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/-DXZksWqf2waNHeU9YTQe/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/jobs","query":{},"buildId":"-DXZksWqf2waNHeU9YTQe","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/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-
|
|
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-339efec49c0cc7d0.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-491a4d699d95e808.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/users-7ed36e44e779d5c7.js" defer=""></script><script src="/dashboard/_next/static/-DXZksWqf2waNHeU9YTQe/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/-DXZksWqf2waNHeU9YTQe/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/users","query":{},"buildId":"-DXZksWqf2waNHeU9YTQe","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-
|
|
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-339efec49c0cc7d0.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-491a4d699d95e808.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/volumes-c9695d657f78b5dc.js" defer=""></script><script src="/dashboard/_next/static/-DXZksWqf2waNHeU9YTQe/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/-DXZksWqf2waNHeU9YTQe/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/volumes","query":{},"buildId":"-DXZksWqf2waNHeU9YTQe","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-
|
|
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-339efec49c0cc7d0.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-491a4d699d95e808.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/workspace/new-3f88a1c7e86a3f86.js" defer=""></script><script src="/dashboard/_next/static/-DXZksWqf2waNHeU9YTQe/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/-DXZksWqf2waNHeU9YTQe/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/workspace/new","query":{},"buildId":"-DXZksWqf2waNHeU9YTQe","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-
|
|
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-339efec49c0cc7d0.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-491a4d699d95e808.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-c9686994ddafcf01.js" defer=""></script><script src="/dashboard/_next/static/chunks/6990-0f886f16e0d55ff8.js" defer=""></script><script src="/dashboard/_next/static/chunks/8056-34d27f51e6d1c631.js" defer=""></script><script src="/dashboard/_next/static/chunks/6135-85426374db04811e.js" defer=""></script><script src="/dashboard/_next/static/chunks/6601-06114c982db410b6.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/-DXZksWqf2waNHeU9YTQe/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/-DXZksWqf2waNHeU9YTQe/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/workspaces/[name]","query":{},"buildId":"-DXZksWqf2waNHeU9YTQe","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-
|
|
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-339efec49c0cc7d0.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-491a4d699d95e808.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/workspaces-8f67be60165724cc.js" defer=""></script><script src="/dashboard/_next/static/-DXZksWqf2waNHeU9YTQe/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/-DXZksWqf2waNHeU9YTQe/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/workspaces","query":{},"buildId":"-DXZksWqf2waNHeU9YTQe","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
|
sky/execution.py
CHANGED
|
@@ -353,12 +353,13 @@ def _execute_dag(
|
|
|
353
353
|
task = _maybe_clone_disk_from_cluster(clone_disk_from, cluster_name,
|
|
354
354
|
task)
|
|
355
355
|
|
|
356
|
+
is_managed = (_is_launched_by_jobs_controller or
|
|
357
|
+
_is_launched_by_sky_serve_controller)
|
|
358
|
+
|
|
356
359
|
if not cluster_exists:
|
|
357
360
|
# If spot is launched on serve or jobs controller, we don't need to
|
|
358
361
|
# print out the hint.
|
|
359
|
-
if (Stage.PROVISION in stages and task.use_spot and
|
|
360
|
-
not _is_launched_by_jobs_controller and
|
|
361
|
-
not _is_launched_by_sky_serve_controller):
|
|
362
|
+
if (Stage.PROVISION in stages and task.use_spot and not is_managed):
|
|
362
363
|
yellow = colorama.Fore.YELLOW
|
|
363
364
|
bold = colorama.Style.BRIGHT
|
|
364
365
|
reset = colorama.Style.RESET_ALL
|
|
@@ -397,7 +398,8 @@ def _execute_dag(
|
|
|
397
398
|
# That's because we want to do commands in task.setup and task.run again
|
|
398
399
|
# after K8S pod recovers from a crash.
|
|
399
400
|
# See `kubernetes-ray.yml.j2` for more details.
|
|
400
|
-
dump_final_script=is_controller_high_availability_supported
|
|
401
|
+
dump_final_script=is_controller_high_availability_supported,
|
|
402
|
+
is_managed=is_managed)
|
|
401
403
|
|
|
402
404
|
if task.storage_mounts is not None:
|
|
403
405
|
# Optimizer should eventually choose where to store bucket
|
sky/global_user_state.py
CHANGED
|
@@ -100,6 +100,7 @@ cluster_table = sqlalchemy.Table(
|
|
|
100
100
|
sqlalchemy.Column('last_creation_command',
|
|
101
101
|
sqlalchemy.Text,
|
|
102
102
|
server_default=None),
|
|
103
|
+
sqlalchemy.Column('is_managed', sqlalchemy.Integer, server_default='0'),
|
|
103
104
|
)
|
|
104
105
|
|
|
105
106
|
storage_table = sqlalchemy.Table(
|
|
@@ -428,7 +429,8 @@ def add_or_update_cluster(cluster_name: str,
|
|
|
428
429
|
ready: bool,
|
|
429
430
|
is_launch: bool = True,
|
|
430
431
|
config_hash: Optional[str] = None,
|
|
431
|
-
task_config: Optional[Dict[str, Any]] = None
|
|
432
|
+
task_config: Optional[Dict[str, Any]] = None,
|
|
433
|
+
is_managed: bool = False):
|
|
432
434
|
"""Adds or updates cluster_name -> cluster_handle mapping.
|
|
433
435
|
|
|
434
436
|
Args:
|
|
@@ -441,6 +443,8 @@ def add_or_update_cluster(cluster_name: str,
|
|
|
441
443
|
and last_use will be updated. Otherwise, use the old value.
|
|
442
444
|
config_hash: Configuration hash for the cluster.
|
|
443
445
|
task_config: The config of the task being launched.
|
|
446
|
+
is_managed: Whether the cluster is launched by the
|
|
447
|
+
controller.
|
|
444
448
|
"""
|
|
445
449
|
assert _SQLALCHEMY_ENGINE is not None
|
|
446
450
|
# FIXME: launched_at will be changed when `sky launch -c` is called.
|
|
@@ -544,6 +548,7 @@ def add_or_update_cluster(cluster_name: str,
|
|
|
544
548
|
cluster_hash=cluster_hash,
|
|
545
549
|
# set storage_mounts_metadata to server default (null)
|
|
546
550
|
status_updated_at=status_updated_at,
|
|
551
|
+
is_managed=int(is_managed),
|
|
547
552
|
)
|
|
548
553
|
do_update_stmt = insert_stmnt.on_conflict_do_update(
|
|
549
554
|
index_elements=[cluster_table.c.name],
|
|
@@ -965,6 +970,7 @@ def get_cluster_from_name(
|
|
|
965
970
|
'workspace': row.workspace,
|
|
966
971
|
'last_creation_yaml': row.last_creation_yaml,
|
|
967
972
|
'last_creation_command': row.last_creation_command,
|
|
973
|
+
'is_managed': bool(row.is_managed),
|
|
968
974
|
}
|
|
969
975
|
|
|
970
976
|
return record
|
|
@@ -1003,6 +1009,7 @@ def get_clusters() -> List[Dict[str, Any]]:
|
|
|
1003
1009
|
'workspace': row.workspace,
|
|
1004
1010
|
'last_creation_yaml': row.last_creation_yaml,
|
|
1005
1011
|
'last_creation_command': row.last_creation_command,
|
|
1012
|
+
'is_managed': bool(row.is_managed),
|
|
1006
1013
|
}
|
|
1007
1014
|
|
|
1008
1015
|
records.append(record)
|
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, Sequence, Union
|
|
4
|
+
from typing import Any, Dict, List, Optional, Sequence, Tuple, Union
|
|
5
5
|
|
|
6
6
|
import click
|
|
7
7
|
|
|
@@ -26,6 +26,7 @@ if typing.TYPE_CHECKING:
|
|
|
26
26
|
import webbrowser
|
|
27
27
|
|
|
28
28
|
import sky
|
|
29
|
+
from sky import backends
|
|
29
30
|
from sky.serve import serve_utils
|
|
30
31
|
else:
|
|
31
32
|
# only used in dashboard()
|
|
@@ -45,7 +46,8 @@ def launch(
|
|
|
45
46
|
# Internal only:
|
|
46
47
|
# pylint: disable=invalid-name
|
|
47
48
|
_need_confirmation: bool = False,
|
|
48
|
-
) -> server_common.RequestId
|
|
49
|
+
) -> server_common.RequestId[Tuple[Optional[int],
|
|
50
|
+
Optional['backends.ResourceHandle']]]:
|
|
49
51
|
"""Launches a managed job.
|
|
50
52
|
|
|
51
53
|
Please refer to sky.cli.job_launch for documentation.
|
|
@@ -86,11 +88,11 @@ def launch(
|
|
|
86
88
|
if _need_confirmation:
|
|
87
89
|
job_identity = 'a managed job'
|
|
88
90
|
if pool is None:
|
|
89
|
-
|
|
90
|
-
sdk.stream_and_get(
|
|
91
|
+
optimize_request_id = sdk.optimize(dag)
|
|
92
|
+
sdk.stream_and_get(optimize_request_id)
|
|
91
93
|
else:
|
|
92
|
-
|
|
93
|
-
pool_statuses = sdk.get(
|
|
94
|
+
pool_status_request_id = pool_status(pool)
|
|
95
|
+
pool_statuses = sdk.get(pool_status_request_id)
|
|
94
96
|
if not pool_statuses:
|
|
95
97
|
raise click.UsageError(f'Pool {pool!r} not found.')
|
|
96
98
|
resources = pool_statuses[0]['requested_resources_str']
|
|
@@ -123,10 +125,12 @@ def launch(
|
|
|
123
125
|
|
|
124
126
|
@usage_lib.entrypoint
|
|
125
127
|
@server_common.check_server_healthy_or_start
|
|
126
|
-
def queue(
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
128
|
+
def queue(
|
|
129
|
+
refresh: bool,
|
|
130
|
+
skip_finished: bool = False,
|
|
131
|
+
all_users: bool = False,
|
|
132
|
+
job_ids: Optional[List[int]] = None
|
|
133
|
+
) -> server_common.RequestId[List[Dict[str, Any]]]:
|
|
130
134
|
"""Gets statuses of managed jobs.
|
|
131
135
|
|
|
132
136
|
Please refer to sky.cli.job_queue for documentation.
|
|
@@ -190,7 +194,7 @@ def cancel(
|
|
|
190
194
|
all: bool = False, # pylint: disable=redefined-builtin
|
|
191
195
|
all_users: bool = False,
|
|
192
196
|
pool: Optional[str] = None,
|
|
193
|
-
) -> server_common.RequestId:
|
|
197
|
+
) -> server_common.RequestId[None]:
|
|
194
198
|
"""Cancels managed jobs.
|
|
195
199
|
|
|
196
200
|
Please refer to sky.cli.job_cancel for documentation.
|
|
@@ -278,7 +282,8 @@ def tail_logs(name: Optional[str] = None,
|
|
|
278
282
|
json=json.loads(body.model_dump_json()),
|
|
279
283
|
stream=True,
|
|
280
284
|
timeout=(5, None))
|
|
281
|
-
request_id = server_common.get_request_id(
|
|
285
|
+
request_id: server_common.RequestId[int] = server_common.get_request_id(
|
|
286
|
+
response)
|
|
282
287
|
# Log request is idempotent when tail is 0, thus can resume previous
|
|
283
288
|
# streaming point on retry.
|
|
284
289
|
return sdk.stream_response(request_id=request_id,
|
|
@@ -326,12 +331,13 @@ def download_logs(
|
|
|
326
331
|
'/jobs/download_logs',
|
|
327
332
|
json=json.loads(body.model_dump_json()),
|
|
328
333
|
timeout=(5, None))
|
|
329
|
-
|
|
330
|
-
server_common.get_request_id(response)
|
|
334
|
+
request_id: server_common.RequestId[Dict[
|
|
335
|
+
str, str]] = server_common.get_request_id(response)
|
|
336
|
+
job_id_remote_path_dict = sdk.stream_and_get(request_id)
|
|
331
337
|
remote2local_path_dict = client_common.download_logs_from_api_server(
|
|
332
338
|
job_id_remote_path_dict.values())
|
|
333
339
|
return {
|
|
334
|
-
job_id: remote2local_path_dict[remote_path]
|
|
340
|
+
int(job_id): remote2local_path_dict[remote_path]
|
|
335
341
|
for job_id, remote_path in job_id_remote_path_dict.items()
|
|
336
342
|
}
|
|
337
343
|
|
|
@@ -380,7 +386,7 @@ def pool_apply(
|
|
|
380
386
|
# Internal only:
|
|
381
387
|
# pylint: disable=invalid-name
|
|
382
388
|
_need_confirmation: bool = False
|
|
383
|
-
) -> server_common.RequestId:
|
|
389
|
+
) -> server_common.RequestId[None]:
|
|
384
390
|
"""Apply a config to a pool."""
|
|
385
391
|
return impl.apply(task,
|
|
386
392
|
pool_name,
|
|
@@ -396,7 +402,7 @@ def pool_down(
|
|
|
396
402
|
pool_names: Optional[Union[str, List[str]]],
|
|
397
403
|
all: bool = False, # pylint: disable=redefined-builtin
|
|
398
404
|
purge: bool = False,
|
|
399
|
-
) -> server_common.RequestId:
|
|
405
|
+
) -> server_common.RequestId[None]:
|
|
400
406
|
"""Delete a pool."""
|
|
401
407
|
return impl.down(pool_names, all, purge, pool=True)
|
|
402
408
|
|
|
@@ -405,7 +411,8 @@ def pool_down(
|
|
|
405
411
|
@server_common.check_server_healthy_or_start
|
|
406
412
|
@versions.minimal_api_version(12)
|
|
407
413
|
def pool_status(
|
|
408
|
-
pool_names: Optional[Union[str, List[str]]],
|
|
414
|
+
pool_names: Optional[Union[str, List[str]]],
|
|
415
|
+
) -> server_common.RequestId[List[Dict[str, Any]]]:
|
|
409
416
|
"""Query a pool."""
|
|
410
417
|
return impl.status(pool_names, pool=True)
|
|
411
418
|
|
|
@@ -413,7 +420,7 @@ def pool_status(
|
|
|
413
420
|
@usage_lib.entrypoint
|
|
414
421
|
@server_common.check_server_healthy_or_start
|
|
415
422
|
@rest.retry_transient_errors()
|
|
416
|
-
@versions.minimal_api_version(
|
|
423
|
+
@versions.minimal_api_version(16)
|
|
417
424
|
def pool_tail_logs(pool_name: str,
|
|
418
425
|
target: Union[str, 'serve_utils.ServiceComponent'],
|
|
419
426
|
worker_id: Optional[int] = None,
|
|
@@ -433,7 +440,7 @@ def pool_tail_logs(pool_name: str,
|
|
|
433
440
|
@usage_lib.entrypoint
|
|
434
441
|
@server_common.check_server_healthy_or_start
|
|
435
442
|
@rest.retry_transient_errors()
|
|
436
|
-
@versions.minimal_api_version(
|
|
443
|
+
@versions.minimal_api_version(16)
|
|
437
444
|
def pool_sync_down_logs(pool_name: str,
|
|
438
445
|
local_dir: str,
|
|
439
446
|
*,
|
sky/jobs/controller.py
CHANGED
|
@@ -332,7 +332,8 @@ class JobsController:
|
|
|
332
332
|
clusters = backend_utils.get_clusters(
|
|
333
333
|
cluster_names=[cluster_name],
|
|
334
334
|
refresh=common.StatusRefreshMode.NONE,
|
|
335
|
-
all_users=True
|
|
335
|
+
all_users=True,
|
|
336
|
+
_include_is_managed=True)
|
|
336
337
|
if clusters:
|
|
337
338
|
assert len(clusters) == 1, (clusters, cluster_name)
|
|
338
339
|
handle = clusters[0].get('handle')
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"""fix initial revision
|
|
2
|
+
|
|
3
|
+
Revision ID: 003
|
|
4
|
+
Revises: 002
|
|
5
|
+
Create Date: 2025-08-07
|
|
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() -> None:
|
|
24
|
+
"""Upgrade schema."""
|
|
25
|
+
with op.get_context().autocommit_block():
|
|
26
|
+
# add missing columns to clusters table
|
|
27
|
+
db_utils.add_column_to_table_alembic('clusters',
|
|
28
|
+
'storage_mounts_metadata',
|
|
29
|
+
sa.LargeBinary(),
|
|
30
|
+
server_default=None)
|
|
31
|
+
# Set the value to replace existing entries to 1 so that all the
|
|
32
|
+
# existing clusters before #2977 are considered as ever up, i.e:
|
|
33
|
+
# existing cluster's default (null) -> 1;
|
|
34
|
+
# new cluster's default -> 0;
|
|
35
|
+
# This is conservative for the existing clusters: even if some INIT
|
|
36
|
+
# clusters were never really UP, setting it to 1 means they won't be
|
|
37
|
+
# auto-deleted during any failover.
|
|
38
|
+
db_utils.add_column_to_table_alembic(
|
|
39
|
+
'clusters',
|
|
40
|
+
'cluster_ever_up',
|
|
41
|
+
sa.Integer(),
|
|
42
|
+
server_default='0',
|
|
43
|
+
value_to_replace_existing_entries=1)
|
|
44
|
+
db_utils.add_column_to_table_alembic('clusters',
|
|
45
|
+
'status_updated_at',
|
|
46
|
+
sa.Integer(),
|
|
47
|
+
server_default=None)
|
|
48
|
+
|
|
49
|
+
# remove mistakenly added columns
|
|
50
|
+
db_utils.drop_column_from_table_alembic('clusters', 'launched_nodes')
|
|
51
|
+
db_utils.drop_column_from_table_alembic('clusters', 'disk_tier')
|
|
52
|
+
db_utils.drop_column_from_table_alembic('clusters',
|
|
53
|
+
'config_hash_locked')
|
|
54
|
+
db_utils.drop_column_from_table_alembic('clusters', 'handle_locked')
|
|
55
|
+
db_utils.drop_column_from_table_alembic('clusters', 'num_failures')
|
|
56
|
+
db_utils.drop_column_from_table_alembic('clusters', 'configs')
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def downgrade() -> None:
|
|
60
|
+
"""Downgrade schema."""
|
|
61
|
+
pass
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"""Columns for whether the cluster is managed.
|
|
2
|
+
|
|
3
|
+
Revision ID: 004
|
|
4
|
+
Revises: 003
|
|
5
|
+
Create Date: 2025-08-07
|
|
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 = '004'
|
|
18
|
+
down_revision: Union[str, Sequence[str], None] = '003'
|
|
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 whether the cluster is managed."""
|
|
25
|
+
with op.get_context().autocommit_block():
|
|
26
|
+
db_utils.add_column_to_table_alembic('clusters',
|
|
27
|
+
'is_managed',
|
|
28
|
+
sa.Integer(),
|
|
29
|
+
server_default='0')
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def downgrade():
|
|
33
|
+
"""Remove columns for whether the cluster is managed."""
|
|
34
|
+
pass
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"""Initial schema for sky serve state database with backwards compatibility
|
|
2
|
+
|
|
3
|
+
Revision ID: 001
|
|
4
|
+
Revises:
|
|
5
|
+
Create Date: 2024-01-01 12:00:00.000000
|
|
6
|
+
|
|
7
|
+
"""
|
|
8
|
+
# pylint: disable=invalid-name
|
|
9
|
+
import json
|
|
10
|
+
|
|
11
|
+
from alembic import op
|
|
12
|
+
import sqlalchemy as sa
|
|
13
|
+
|
|
14
|
+
from sky.serve import constants
|
|
15
|
+
from sky.serve.serve_state import Base
|
|
16
|
+
from sky.utils.db import db_utils
|
|
17
|
+
|
|
18
|
+
# revision identifiers, used by Alembic.
|
|
19
|
+
revision = '001'
|
|
20
|
+
down_revision = None
|
|
21
|
+
branch_labels = None
|
|
22
|
+
depends_on = None
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def upgrade():
|
|
26
|
+
"""Create initial schema and add all backwards compatibility columns"""
|
|
27
|
+
with op.get_context().autocommit_block():
|
|
28
|
+
# Create all tables with their current schema
|
|
29
|
+
db_utils.add_tables_to_db_sqlalchemy(Base.metadata, op.get_bind())
|
|
30
|
+
|
|
31
|
+
# Add backwards compatibility columns using helper function that matches
|
|
32
|
+
# original add_column_to_table_sqlalchemy behavior exactly
|
|
33
|
+
db_utils.add_column_to_table_alembic('services',
|
|
34
|
+
'requested_resources_str',
|
|
35
|
+
sa.Text())
|
|
36
|
+
db_utils.add_column_to_table_alembic(
|
|
37
|
+
'services',
|
|
38
|
+
'current_version',
|
|
39
|
+
sa.Integer(),
|
|
40
|
+
server_default=f'{constants.INITIAL_VERSION}')
|
|
41
|
+
db_utils.add_column_to_table_alembic('services',
|
|
42
|
+
'active_versions',
|
|
43
|
+
sa.Text(),
|
|
44
|
+
server_default=json.dumps([]))
|
|
45
|
+
db_utils.add_column_to_table_alembic('services',
|
|
46
|
+
'load_balancing_policy', sa.Text())
|
|
47
|
+
db_utils.add_column_to_table_alembic('services',
|
|
48
|
+
'tls_encrypted',
|
|
49
|
+
sa.Integer(),
|
|
50
|
+
server_default='0')
|
|
51
|
+
db_utils.add_column_to_table_alembic('services',
|
|
52
|
+
'pool',
|
|
53
|
+
sa.Integer(),
|
|
54
|
+
server_default='0')
|
|
55
|
+
db_utils.add_column_to_table_alembic(
|
|
56
|
+
'services',
|
|
57
|
+
'controller_pid',
|
|
58
|
+
sa.Integer(),
|
|
59
|
+
value_to_replace_existing_entries=-1)
|
|
60
|
+
db_utils.add_column_to_table_alembic('services', 'hash', sa.Text())
|
|
61
|
+
db_utils.add_column_to_table_alembic('services', 'entrypoint',
|
|
62
|
+
sa.Text())
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def downgrade():
|
|
66
|
+
"""Drop all tables"""
|
|
67
|
+
Base.metadata.drop_all(bind=op.get_bind())
|
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, Sequence, Union
|
|
4
|
+
from typing import Any, Dict, List, Optional, Sequence, Tuple, Union
|
|
5
5
|
|
|
6
6
|
import click
|
|
7
7
|
|
|
@@ -25,7 +25,7 @@ def up(
|
|
|
25
25
|
# Internal only:
|
|
26
26
|
# pylint: disable=invalid-name
|
|
27
27
|
_need_confirmation: bool = False
|
|
28
|
-
) -> server_common.RequestId:
|
|
28
|
+
) -> server_common.RequestId[Tuple[str, str]]:
|
|
29
29
|
assert not pool, 'Command `up` is not supported for pool.'
|
|
30
30
|
# Avoid circular import.
|
|
31
31
|
from sky.client import sdk # pylint: disable=import-outside-toplevel
|
|
@@ -69,7 +69,7 @@ def update(
|
|
|
69
69
|
# Internal only:
|
|
70
70
|
# pylint: disable=invalid-name
|
|
71
71
|
_need_confirmation: bool = False
|
|
72
|
-
) -> server_common.RequestId:
|
|
72
|
+
) -> server_common.RequestId[None]:
|
|
73
73
|
assert not pool, 'Command `update` is not supported for pool.'
|
|
74
74
|
# Avoid circular import.
|
|
75
75
|
from sky.client import sdk # pylint: disable=import-outside-toplevel
|
|
@@ -112,7 +112,7 @@ def apply(
|
|
|
112
112
|
# Internal only:
|
|
113
113
|
# pylint: disable=invalid-name
|
|
114
114
|
_need_confirmation: bool = False
|
|
115
|
-
) -> server_common.RequestId:
|
|
115
|
+
) -> server_common.RequestId[None]:
|
|
116
116
|
assert pool, 'Command `apply` is only supported for pool.'
|
|
117
117
|
# Avoid circular import.
|
|
118
118
|
from sky.client import sdk # pylint: disable=import-outside-toplevel
|
|
@@ -153,7 +153,7 @@ def down(
|
|
|
153
153
|
all: bool = False, # pylint: disable=redefined-builtin
|
|
154
154
|
purge: bool = False,
|
|
155
155
|
pool: bool = False,
|
|
156
|
-
) -> server_common.RequestId:
|
|
156
|
+
) -> server_common.RequestId[None]:
|
|
157
157
|
if pool:
|
|
158
158
|
body = payloads.JobsPoolDownBody(
|
|
159
159
|
pool_names=service_names,
|
|
@@ -177,7 +177,7 @@ def down(
|
|
|
177
177
|
def status(
|
|
178
178
|
service_names: Optional[Union[str, List[str]]],
|
|
179
179
|
pool: bool = False,
|
|
180
|
-
) -> server_common.RequestId:
|
|
180
|
+
) -> server_common.RequestId[List[Dict[str, Any]]]:
|
|
181
181
|
if pool:
|
|
182
182
|
body = payloads.JobsPoolStatusBody(pool_names=service_names)
|
|
183
183
|
else:
|
|
@@ -222,7 +222,8 @@ def tail_logs(service_name: str,
|
|
|
222
222
|
json=json.loads(body.model_dump_json()),
|
|
223
223
|
timeout=(5, None),
|
|
224
224
|
stream=True)
|
|
225
|
-
request_id = server_common.get_request_id(
|
|
225
|
+
request_id: server_common.RequestId[None] = server_common.get_request_id(
|
|
226
|
+
response)
|
|
226
227
|
return sdk.stream_response(request_id=request_id,
|
|
227
228
|
response=response,
|
|
228
229
|
output_stream=output_stream,
|
|
@@ -265,7 +266,9 @@ def sync_down_logs(service_name: str,
|
|
|
265
266
|
'/jobs/pool_sync-down-logs' if pool else '/serve/sync-down-logs',
|
|
266
267
|
json=json.loads(body.model_dump_json()),
|
|
267
268
|
timeout=(5, None))
|
|
268
|
-
|
|
269
|
+
request_id: server_common.RequestId[str] = server_common.get_request_id(
|
|
270
|
+
response)
|
|
271
|
+
remote_dir = sdk.stream_and_get(request_id)
|
|
269
272
|
|
|
270
273
|
# Download from API server paths to the client's local_dir
|
|
271
274
|
client_common.download_logs_from_api_server([remote_dir], remote_dir,
|
sky/serve/client/sdk.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""SDK for SkyServe."""
|
|
2
2
|
import json
|
|
3
3
|
import typing
|
|
4
|
-
from typing import List, Optional, Sequence, Union
|
|
4
|
+
from typing import Any, Dict, List, Optional, Sequence, Tuple, Union
|
|
5
5
|
|
|
6
6
|
from sky.serve.client import impl
|
|
7
7
|
from sky.server import common as server_common
|
|
@@ -26,7 +26,7 @@ def up(
|
|
|
26
26
|
# Internal only:
|
|
27
27
|
# pylint: disable=invalid-name
|
|
28
28
|
_need_confirmation: bool = False
|
|
29
|
-
) -> server_common.RequestId:
|
|
29
|
+
) -> server_common.RequestId[Tuple[str, str]]:
|
|
30
30
|
"""Spins up a service.
|
|
31
31
|
|
|
32
32
|
Please refer to the sky.cli.serve_up for the document.
|
|
@@ -61,7 +61,7 @@ def update(
|
|
|
61
61
|
# Internal only:
|
|
62
62
|
# pylint: disable=invalid-name
|
|
63
63
|
_need_confirmation: bool = False
|
|
64
|
-
) -> server_common.RequestId:
|
|
64
|
+
) -> server_common.RequestId[None]:
|
|
65
65
|
"""Updates an existing service.
|
|
66
66
|
|
|
67
67
|
Please refer to the sky.cli.serve_update for the document.
|
|
@@ -94,7 +94,7 @@ def down(
|
|
|
94
94
|
service_names: Optional[Union[str, List[str]]],
|
|
95
95
|
all: bool = False, # pylint: disable=redefined-builtin
|
|
96
96
|
purge: bool = False
|
|
97
|
-
) -> server_common.RequestId:
|
|
97
|
+
) -> server_common.RequestId[None]:
|
|
98
98
|
"""Tears down a service.
|
|
99
99
|
|
|
100
100
|
Please refer to the sky.cli.serve_down for the docs.
|
|
@@ -122,7 +122,7 @@ def down(
|
|
|
122
122
|
@usage_lib.entrypoint
|
|
123
123
|
@server_common.check_server_healthy_or_start
|
|
124
124
|
def terminate_replica(service_name: str, replica_id: int,
|
|
125
|
-
purge: bool) -> server_common.RequestId:
|
|
125
|
+
purge: bool) -> server_common.RequestId[None]:
|
|
126
126
|
"""Tears down a specific replica for the given service.
|
|
127
127
|
|
|
128
128
|
Args:
|
|
@@ -156,8 +156,8 @@ def terminate_replica(service_name: str, replica_id: int,
|
|
|
156
156
|
@usage_lib.entrypoint
|
|
157
157
|
@server_common.check_server_healthy_or_start
|
|
158
158
|
def status(
|
|
159
|
-
|
|
160
|
-
|
|
159
|
+
service_names: Optional[Union[str, List[str]]]
|
|
160
|
+
) -> server_common.RequestId[List[Dict[str, Any]]]:
|
|
161
161
|
"""Gets service statuses.
|
|
162
162
|
|
|
163
163
|
If service_names is given, return those services. Otherwise, return all
|