skypilot-nightly 1.0.0.dev20250818__py3-none-any.whl → 1.0.0.dev20250820__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 +5 -3
- sky/backends/cloud_vm_ray_backend.py +6 -13
- sky/backends/wheel_utils.py +2 -1
- sky/catalog/data_fetchers/fetch_aws.py +2 -0
- sky/client/cli/command.py +20 -16
- sky/core.py +1 -1
- sky/dashboard/out/404.html +1 -1
- sky/dashboard/out/_next/static/{D7_ocVBIBwyxtvXYWggqV → 8ZscIHnvBWz3AXkxsJL6H}/_buildManifest.js +1 -1
- sky/dashboard/out/_next/static/chunks/3015-bf218e4973bf5c8f.js +1 -0
- sky/dashboard/out/_next/static/chunks/{8969-6cb1af4ec7fb1e19.js → 8969-23c8fbdb8b397d59.js} +1 -1
- sky/dashboard/out/_next/static/chunks/{webpack-a46c8b62df807ec1.js → webpack-008593a02784a2df.js} +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/exceptions.py +6 -1
- sky/global_user_state.py +18 -11
- sky/jobs/constants.py +1 -1
- sky/jobs/server/core.py +43 -34
- sky/jobs/server/utils.py +2 -1
- sky/jobs/utils.py +56 -9
- sky/models.py +1 -0
- sky/provision/aws/config.py +11 -11
- sky/provision/aws/instance.py +30 -27
- sky/provision/do/utils.py +2 -2
- sky/provision/kubernetes/network_utils.py +3 -3
- sky/provision/kubernetes/utils.py +2 -2
- sky/provision/kubernetes/volume.py +2 -0
- sky/provision/provisioner.py +10 -6
- sky/serve/replica_managers.py +7 -0
- sky/serve/server/impl.py +1 -1
- sky/server/requests/payloads.py +2 -0
- sky/server/requests/serializers/encoders.py +29 -5
- sky/server/server.py +37 -1
- sky/setup_files/MANIFEST.in +1 -0
- sky/setup_files/dependencies.py +17 -11
- sky/skylet/ray_patches/__init__.py +18 -4
- sky/skylet/ray_patches/autoscaler.py.diff +18 -0
- sky/skylet/ray_patches/cli.py.diff +19 -0
- sky/skylet/ray_patches/command_runner.py.diff +17 -0
- sky/skylet/ray_patches/log_monitor.py.diff +20 -0
- sky/skylet/ray_patches/resource_demand_scheduler.py.diff +32 -0
- sky/skylet/ray_patches/updater.py.diff +18 -0
- sky/skylet/ray_patches/worker.py.diff +41 -0
- sky/utils/common.py +27 -7
- sky/utils/common_utils.py +13 -9
- sky/utils/directory_utils.py +12 -0
- sky/utils/env_options.py +3 -0
- sky/utils/kubernetes/gpu_labeler.py +3 -3
- sky/utils/schemas.py +1 -0
- sky/utils/serialize_utils.py +16 -0
- sky/volumes/client/sdk.py +10 -7
- sky/volumes/server/core.py +12 -3
- sky/volumes/volume.py +17 -3
- {skypilot_nightly-1.0.0.dev20250818.dist-info → skypilot_nightly-1.0.0.dev20250820.dist-info}/METADATA +21 -13
- {skypilot_nightly-1.0.0.dev20250818.dist-info → skypilot_nightly-1.0.0.dev20250820.dist-info}/RECORD +72 -63
- sky/dashboard/out/_next/static/chunks/3015-471d67c9302d4027.js +0 -1
- /sky/dashboard/out/_next/static/{D7_ocVBIBwyxtvXYWggqV → 8ZscIHnvBWz3AXkxsJL6H}/_ssgManifest.js +0 -0
- {skypilot_nightly-1.0.0.dev20250818.dist-info → skypilot_nightly-1.0.0.dev20250820.dist-info}/WHEEL +0 -0
- {skypilot_nightly-1.0.0.dev20250818.dist-info → skypilot_nightly-1.0.0.dev20250820.dist-info}/entry_points.txt +0 -0
- {skypilot_nightly-1.0.0.dev20250818.dist-info → skypilot_nightly-1.0.0.dev20250820.dist-info}/licenses/LICENSE +0 -0
- {skypilot_nightly-1.0.0.dev20250818.dist-info → skypilot_nightly-1.0.0.dev20250820.dist-info}/top_level.txt +0 -0
sky/dashboard/out/index.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-008593a02784a2df.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/index-444f1804401f04ea.js" defer=""></script><script src="/dashboard/_next/static/8ZscIHnvBWz3AXkxsJL6H/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/8ZscIHnvBWz3AXkxsJL6H/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/","query":{},"buildId":"8ZscIHnvBWz3AXkxsJL6H","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-008593a02784a2df.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/infra/%5Bcontext%5D-81351f95f3bec08e.js" defer=""></script><script src="/dashboard/_next/static/8ZscIHnvBWz3AXkxsJL6H/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/8ZscIHnvBWz3AXkxsJL6H/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/infra/[context]","query":{},"buildId":"8ZscIHnvBWz3AXkxsJL6H","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
|
sky/dashboard/out/infra.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-008593a02784a2df.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/infra-c320641c2bcbbea6.js" defer=""></script><script src="/dashboard/_next/static/8ZscIHnvBWz3AXkxsJL6H/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/8ZscIHnvBWz3AXkxsJL6H/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/infra","query":{},"buildId":"8ZscIHnvBWz3AXkxsJL6H","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-008593a02784a2df.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/754-d0da8ab45f9509e9.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-23c8fbdb8b397d59.js" defer=""></script><script src="/dashboard/_next/static/chunks/6135-4b4d5e824b7f9d3c.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/jobs/%5Bjob%5D-ad2cd5aab787bc15.js" defer=""></script><script src="/dashboard/_next/static/8ZscIHnvBWz3AXkxsJL6H/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/8ZscIHnvBWz3AXkxsJL6H/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/jobs/[job]","query":{},"buildId":"8ZscIHnvBWz3AXkxsJL6H","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-008593a02784a2df.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/1272-1ef0bf0237faccdb.js" defer=""></script><script src="/dashboard/_next/static/chunks/754-d0da8ab45f9509e9.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-23c8fbdb8b397d59.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/jobs/pools/%5Bpool%5D-7d4182df6625fe10.js" defer=""></script><script src="/dashboard/_next/static/8ZscIHnvBWz3AXkxsJL6H/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/8ZscIHnvBWz3AXkxsJL6H/_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":"8ZscIHnvBWz3AXkxsJL6H","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-008593a02784a2df.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/jobs-4b3ba1792dc6f21d.js" defer=""></script><script src="/dashboard/_next/static/8ZscIHnvBWz3AXkxsJL6H/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/8ZscIHnvBWz3AXkxsJL6H/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/jobs","query":{},"buildId":"8ZscIHnvBWz3AXkxsJL6H","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-008593a02784a2df.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/8ZscIHnvBWz3AXkxsJL6H/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/8ZscIHnvBWz3AXkxsJL6H/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/users","query":{},"buildId":"8ZscIHnvBWz3AXkxsJL6H","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-008593a02784a2df.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/8ZscIHnvBWz3AXkxsJL6H/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/8ZscIHnvBWz3AXkxsJL6H/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/volumes","query":{},"buildId":"8ZscIHnvBWz3AXkxsJL6H","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-008593a02784a2df.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/8ZscIHnvBWz3AXkxsJL6H/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/8ZscIHnvBWz3AXkxsJL6H/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/workspace/new","query":{},"buildId":"8ZscIHnvBWz3AXkxsJL6H","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-008593a02784a2df.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/6633-efe924b9b8136699.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-23c8fbdb8b397d59.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-2edb8ab2ba080a76.js" defer=""></script><script src="/dashboard/_next/static/chunks/6601-06114c982db410b6.js" defer=""></script><script src="/dashboard/_next/static/chunks/3015-bf218e4973bf5c8f.js" defer=""></script><script src="/dashboard/_next/static/chunks/1141-2f60a90b7d76838e.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/workspaces/%5Bname%5D-65f72dee417237ef.js" defer=""></script><script src="/dashboard/_next/static/8ZscIHnvBWz3AXkxsJL6H/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/8ZscIHnvBWz3AXkxsJL6H/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/workspaces/[name]","query":{},"buildId":"8ZscIHnvBWz3AXkxsJL6H","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-008593a02784a2df.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-338de9df523d883a.js" defer=""></script><script src="/dashboard/_next/static/8ZscIHnvBWz3AXkxsJL6H/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/8ZscIHnvBWz3AXkxsJL6H/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/workspaces","query":{},"buildId":"8ZscIHnvBWz3AXkxsJL6H","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
|
sky/exceptions.py
CHANGED
|
@@ -6,11 +6,12 @@ import types
|
|
|
6
6
|
import typing
|
|
7
7
|
from typing import Any, Dict, List, Optional, Sequence
|
|
8
8
|
|
|
9
|
+
from sky.backends import backend
|
|
9
10
|
from sky.utils import env_options
|
|
11
|
+
from sky.utils import serialize_utils
|
|
10
12
|
|
|
11
13
|
if typing.TYPE_CHECKING:
|
|
12
14
|
from sky import jobs as managed_jobs
|
|
13
|
-
from sky.backends import backend
|
|
14
15
|
from sky.skylet import job_lib
|
|
15
16
|
from sky.utils import status_lib
|
|
16
17
|
|
|
@@ -92,6 +93,10 @@ def serialize_exception(e: BaseException) -> Dict[str, Any]:
|
|
|
92
93
|
attr_v = attributes[attr_k]
|
|
93
94
|
if isinstance(attr_v, types.TracebackType):
|
|
94
95
|
attributes[attr_k] = traceback.format_tb(attr_v)
|
|
96
|
+
if isinstance(attr_v, backend.ResourceHandle):
|
|
97
|
+
attributes[attr_k] = (
|
|
98
|
+
serialize_utils.prepare_handle_for_backwards_compatibility(
|
|
99
|
+
attr_v))
|
|
95
100
|
|
|
96
101
|
data = {
|
|
97
102
|
'type': e.__class__.__name__,
|
sky/global_user_state.py
CHANGED
|
@@ -55,6 +55,13 @@ _SQLALCHEMY_ENGINE_LOCK = threading.Lock()
|
|
|
55
55
|
DEFAULT_CLUSTER_EVENT_RETENTION_HOURS = 24.0
|
|
56
56
|
MIN_CLUSTER_EVENT_DAEMON_INTERVAL_SECONDS = 3600
|
|
57
57
|
|
|
58
|
+
_UNIQUE_CONSTRAINT_FAILED_ERROR_MSGS = [
|
|
59
|
+
# sqlite
|
|
60
|
+
'UNIQUE constraint failed',
|
|
61
|
+
# postgres
|
|
62
|
+
'duplicate key value violates unique constraint',
|
|
63
|
+
]
|
|
64
|
+
|
|
58
65
|
Base = declarative.declarative_base()
|
|
59
66
|
|
|
60
67
|
config_table = sqlalchemy.Table(
|
|
@@ -735,17 +742,17 @@ def add_cluster_event(cluster_name: str,
|
|
|
735
742
|
))
|
|
736
743
|
session.commit()
|
|
737
744
|
except sqlalchemy.exc.IntegrityError as e:
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
745
|
+
for msg in _UNIQUE_CONSTRAINT_FAILED_ERROR_MSGS:
|
|
746
|
+
if msg in str(e):
|
|
747
|
+
# This can happen if the cluster event is added twice.
|
|
748
|
+
# We can ignore this error unless the caller requests
|
|
749
|
+
# to expose the error.
|
|
750
|
+
if expose_duplicate_error:
|
|
751
|
+
raise db_utils.UniqueConstraintViolationError(
|
|
752
|
+
value=reason, message=str(e))
|
|
753
|
+
else:
|
|
754
|
+
return
|
|
755
|
+
raise e
|
|
749
756
|
|
|
750
757
|
|
|
751
758
|
def get_last_cluster_event(cluster_hash: str,
|
sky/jobs/constants.py
CHANGED
|
@@ -47,7 +47,7 @@ JOBS_CLUSTER_NAME_PREFIX_LENGTH = 25
|
|
|
47
47
|
# The version of the lib files that jobs/utils use. Whenever there is an API
|
|
48
48
|
# change for the jobs/utils, we need to bump this version and update
|
|
49
49
|
# job.utils.ManagedJobCodeGen to handle the version update.
|
|
50
|
-
MANAGED_JOBS_VERSION =
|
|
50
|
+
MANAGED_JOBS_VERSION = 10
|
|
51
51
|
|
|
52
52
|
# The command for setting up the jobs dashboard on the controller. It firstly
|
|
53
53
|
# checks if the systemd services are available, and if not (e.g., Kubernetes
|
sky/jobs/server/core.py
CHANGED
|
@@ -188,11 +188,11 @@ def launch(
|
|
|
188
188
|
|
|
189
189
|
dag_uuid = str(uuid.uuid4().hex[:4])
|
|
190
190
|
dag = dag_utils.convert_entrypoint_to_dag(entrypoint)
|
|
191
|
-
dag.resolve_and_validate_volumes()
|
|
192
191
|
# Always apply the policy again here, even though it might have been applied
|
|
193
192
|
# in the CLI. This is to ensure that we apply the policy to the final DAG
|
|
194
193
|
# and get the mutated config.
|
|
195
194
|
dag, mutated_user_config = admin_policy_utils.apply(dag)
|
|
195
|
+
dag.resolve_and_validate_volumes()
|
|
196
196
|
if not dag.is_chain():
|
|
197
197
|
with ux_utils.print_exception_no_traceback():
|
|
198
198
|
raise ValueError('Only single-task or chain DAG is '
|
|
@@ -514,7 +514,7 @@ def queue_from_kubernetes_pod(
|
|
|
514
514
|
except exceptions.CommandError as e:
|
|
515
515
|
raise RuntimeError(str(e)) from e
|
|
516
516
|
|
|
517
|
-
jobs, _, result_type = managed_job_utils.load_managed_job_queue(
|
|
517
|
+
jobs, _, result_type, _, _ = managed_job_utils.load_managed_job_queue(
|
|
518
518
|
job_table_payload)
|
|
519
519
|
|
|
520
520
|
if result_type == managed_job_utils.ManagedJobQueueResultType.DICT:
|
|
@@ -587,31 +587,36 @@ def queue(
|
|
|
587
587
|
pool_match: Optional[str] = None,
|
|
588
588
|
page: Optional[int] = None,
|
|
589
589
|
limit: Optional[int] = None,
|
|
590
|
-
|
|
590
|
+
statuses: Optional[List[str]] = None,
|
|
591
|
+
) -> Tuple[List[Dict[str, Any]], int, Dict[str, int], int]:
|
|
591
592
|
# NOTE(dev): Keep the docstring consistent between the Python API and CLI.
|
|
592
593
|
"""Gets statuses of managed jobs.
|
|
593
594
|
|
|
594
595
|
Please refer to sky.cli.job_queue for documentation.
|
|
595
596
|
|
|
596
597
|
Returns:
|
|
597
|
-
[
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
598
|
+
jobs: List[Dict[str, Any]]
|
|
599
|
+
[
|
|
600
|
+
{
|
|
601
|
+
'job_id': int,
|
|
602
|
+
'job_name': str,
|
|
603
|
+
'resources': str,
|
|
604
|
+
'submitted_at': (float) timestamp of submission,
|
|
605
|
+
'end_at': (float) timestamp of end,
|
|
606
|
+
'job_duration': (float) duration in seconds,
|
|
607
|
+
'recovery_count': (int) Number of retries,
|
|
608
|
+
'status': (sky.jobs.ManagedJobStatus) of the job,
|
|
609
|
+
'cluster_resources': (str) resources of the cluster,
|
|
610
|
+
'region': (str) region of the cluster,
|
|
611
|
+
'user_name': (Optional[str]) job creator's user name,
|
|
612
|
+
'user_hash': (str) job creator's user hash,
|
|
613
|
+
'task_id': (int), set to 0 (except in pipelines, which may have multiple tasks), # pylint: disable=line-too-long
|
|
614
|
+
'task_name': (str), same as job_name (except in pipelines, which may have multiple tasks), # pylint: disable=line-too-long
|
|
615
|
+
}
|
|
616
|
+
]
|
|
617
|
+
total: int, total number of jobs after filter
|
|
618
|
+
status_counts: Dict[str, int], status counts after filter
|
|
619
|
+
total_no_filter: int, total number of jobs before filter
|
|
615
620
|
Raises:
|
|
616
621
|
sky.exceptions.ClusterNotUpError: the jobs controller is not up or
|
|
617
622
|
does not exist.
|
|
@@ -645,13 +650,13 @@ def queue(
|
|
|
645
650
|
elif user_match is not None:
|
|
646
651
|
users = global_user_state.get_user_by_name_match(user_match)
|
|
647
652
|
if not users:
|
|
648
|
-
return [], 0
|
|
653
|
+
return [], 0, {}, 0
|
|
649
654
|
user_hashes = [user.id for user in users]
|
|
650
655
|
|
|
651
656
|
accessible_workspaces = list(workspaces_core.get_workspaces().keys())
|
|
652
657
|
code = managed_job_utils.ManagedJobCodeGen.get_job_table(
|
|
653
658
|
skip_finished, accessible_workspaces, job_ids, workspace_match,
|
|
654
|
-
name_match, pool_match, page, limit, user_hashes)
|
|
659
|
+
name_match, pool_match, page, limit, user_hashes, statuses)
|
|
655
660
|
returncode, job_table_payload, stderr = backend.run_on_head(
|
|
656
661
|
handle,
|
|
657
662
|
code,
|
|
@@ -664,11 +669,11 @@ def queue(
|
|
|
664
669
|
raise RuntimeError('Failed to fetch managed jobs with returncode: '
|
|
665
670
|
f'{returncode}.\n{job_table_payload + stderr}')
|
|
666
671
|
|
|
667
|
-
jobs, total, result_type
|
|
668
|
-
|
|
672
|
+
(jobs, total, result_type, total_no_filter, status_counts
|
|
673
|
+
) = managed_job_utils.load_managed_job_queue(job_table_payload)
|
|
669
674
|
|
|
670
675
|
if result_type == managed_job_utils.ManagedJobQueueResultType.DICT:
|
|
671
|
-
return jobs, total
|
|
676
|
+
return jobs, total, status_counts, total_no_filter
|
|
672
677
|
|
|
673
678
|
# Backward compatibility for old jobs controller without filtering
|
|
674
679
|
# TODO(hailong): remove this after 0.12.0
|
|
@@ -702,14 +707,18 @@ def queue(
|
|
|
702
707
|
if job_ids:
|
|
703
708
|
jobs = [job for job in jobs if job['job_id'] in job_ids]
|
|
704
709
|
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
710
|
+
filtered_jobs, total, status_counts = managed_job_utils.filter_jobs(
|
|
711
|
+
jobs,
|
|
712
|
+
workspace_match,
|
|
713
|
+
name_match,
|
|
714
|
+
pool_match,
|
|
715
|
+
page=page,
|
|
716
|
+
limit=limit,
|
|
717
|
+
user_match=user_match,
|
|
718
|
+
enable_user_match=True,
|
|
719
|
+
statuses=statuses,
|
|
720
|
+
)
|
|
721
|
+
return filtered_jobs, total, status_counts, total_no_filter
|
|
713
722
|
|
|
714
723
|
|
|
715
724
|
@usage_lib.entrypoint
|
sky/jobs/server/utils.py
CHANGED
|
@@ -62,7 +62,8 @@ def check_version_mismatch_and_non_terminal_jobs() -> None:
|
|
|
62
62
|
version_matches = controller_version == local_version
|
|
63
63
|
|
|
64
64
|
# Load and filter jobs locally using existing method
|
|
65
|
-
jobs, _, _ = managed_job_utils.load_managed_job_queue(
|
|
65
|
+
jobs, _, _, _, _ = managed_job_utils.load_managed_job_queue(
|
|
66
|
+
job_table_payload)
|
|
66
67
|
non_terminal_jobs = [job for job in jobs if not job['status'].is_terminal()]
|
|
67
68
|
has_non_terminal_jobs = len(non_terminal_jobs) > 0
|
|
68
69
|
|
sky/jobs/utils.py
CHANGED
|
@@ -768,6 +768,13 @@ def stream_logs_by_id(job_id: int,
|
|
|
768
768
|
assert tail > 0
|
|
769
769
|
# Read only the last 'tail' lines using deque
|
|
770
770
|
read_from = collections.deque(f, maxlen=tail)
|
|
771
|
+
# We set start_streaming to True here in case
|
|
772
|
+
# truncating the log file removes the line that
|
|
773
|
+
# contains LOG_FILE_START_STREAMING_AT. This does
|
|
774
|
+
# not cause issues for log files shorter than tail
|
|
775
|
+
# because tail_logs in sky/skylet/log_lib.py also
|
|
776
|
+
# handles LOG_FILE_START_STREAMING_AT.
|
|
777
|
+
start_streaming = True
|
|
771
778
|
for line in read_from:
|
|
772
779
|
if log_lib.LOG_FILE_START_STREAMING_AT in line:
|
|
773
780
|
start_streaming = True
|
|
@@ -1133,6 +1140,7 @@ def dump_managed_job_queue(
|
|
|
1133
1140
|
page: Optional[int] = None,
|
|
1134
1141
|
limit: Optional[int] = None,
|
|
1135
1142
|
user_hashes: Optional[List[Optional[str]]] = None,
|
|
1143
|
+
statuses: Optional[List[str]] = None,
|
|
1136
1144
|
) -> str:
|
|
1137
1145
|
# Make sure to get all jobs - some logic below (e.g. high priority job
|
|
1138
1146
|
# detection) requires a full view of the jobs table.
|
|
@@ -1160,6 +1168,8 @@ def dump_managed_job_queue(
|
|
|
1160
1168
|
if priority is not None and priority > highest_blocking_priority:
|
|
1161
1169
|
highest_blocking_priority = priority
|
|
1162
1170
|
|
|
1171
|
+
total_no_filter = len(jobs)
|
|
1172
|
+
|
|
1163
1173
|
if user_hashes:
|
|
1164
1174
|
jobs = [
|
|
1165
1175
|
job for job in jobs if job.get('user_hash', None) in user_hashes
|
|
@@ -1183,8 +1193,13 @@ def dump_managed_job_queue(
|
|
|
1183
1193
|
if job_ids:
|
|
1184
1194
|
jobs = [job for job in jobs if job['job_id'] in job_ids]
|
|
1185
1195
|
|
|
1186
|
-
jobs, total = filter_jobs(jobs,
|
|
1187
|
-
|
|
1196
|
+
jobs, total, status_counts = filter_jobs(jobs,
|
|
1197
|
+
workspace_match,
|
|
1198
|
+
name_match,
|
|
1199
|
+
pool_match,
|
|
1200
|
+
page,
|
|
1201
|
+
limit,
|
|
1202
|
+
statuses=statuses)
|
|
1188
1203
|
for job in jobs:
|
|
1189
1204
|
end_at = job['end_at']
|
|
1190
1205
|
if end_at is None:
|
|
@@ -1258,7 +1273,12 @@ def dump_managed_job_queue(
|
|
|
1258
1273
|
else:
|
|
1259
1274
|
job['details'] = None
|
|
1260
1275
|
|
|
1261
|
-
return message_utils.encode_payload({
|
|
1276
|
+
return message_utils.encode_payload({
|
|
1277
|
+
'jobs': jobs,
|
|
1278
|
+
'total': total,
|
|
1279
|
+
'total_no_filter': total_no_filter,
|
|
1280
|
+
'status_counts': status_counts
|
|
1281
|
+
})
|
|
1262
1282
|
|
|
1263
1283
|
|
|
1264
1284
|
def filter_jobs(
|
|
@@ -1270,7 +1290,8 @@ def filter_jobs(
|
|
|
1270
1290
|
limit: Optional[int],
|
|
1271
1291
|
user_match: Optional[str] = None,
|
|
1272
1292
|
enable_user_match: bool = False,
|
|
1273
|
-
|
|
1293
|
+
statuses: Optional[List[str]] = None,
|
|
1294
|
+
) -> Tuple[List[Dict[str, Any]], int, Dict[str, int]]:
|
|
1274
1295
|
"""Filter jobs based on the given criteria.
|
|
1275
1296
|
|
|
1276
1297
|
Args:
|
|
@@ -1282,9 +1303,12 @@ def filter_jobs(
|
|
|
1282
1303
|
limit: Limit to filter.
|
|
1283
1304
|
user_match: User name to filter.
|
|
1284
1305
|
enable_user_match: Whether to enable user match.
|
|
1306
|
+
statuses: Statuses to filter.
|
|
1285
1307
|
|
|
1286
1308
|
Returns:
|
|
1287
|
-
List of filtered jobs
|
|
1309
|
+
List of filtered jobs
|
|
1310
|
+
Total number of jobs
|
|
1311
|
+
Dictionary of status counts
|
|
1288
1312
|
"""
|
|
1289
1313
|
|
|
1290
1314
|
# TODO(hailong): refactor the whole function including the
|
|
@@ -1314,6 +1338,7 @@ def filter_jobs(
|
|
|
1314
1338
|
end = min(start + limit, len(result))
|
|
1315
1339
|
return result[start:end]
|
|
1316
1340
|
|
|
1341
|
+
status_counts: Dict[str, int] = collections.defaultdict(int)
|
|
1317
1342
|
result = []
|
|
1318
1343
|
checks = [
|
|
1319
1344
|
('workspace', workspace_match),
|
|
@@ -1327,25 +1352,34 @@ def filter_jobs(
|
|
|
1327
1352
|
if not all(
|
|
1328
1353
|
_pattern_matches(job, key, pattern) for key, pattern in checks):
|
|
1329
1354
|
continue
|
|
1355
|
+
status_counts[job['status'].value] += 1
|
|
1356
|
+
if statuses:
|
|
1357
|
+
if job['status'].value not in statuses:
|
|
1358
|
+
continue
|
|
1330
1359
|
result.append(job)
|
|
1331
1360
|
|
|
1332
1361
|
total = len(result)
|
|
1333
1362
|
|
|
1334
|
-
return _handle_page_and_limit(result, page, limit), total
|
|
1363
|
+
return _handle_page_and_limit(result, page, limit), total, status_counts
|
|
1335
1364
|
|
|
1336
1365
|
|
|
1337
1366
|
def load_managed_job_queue(
|
|
1338
1367
|
payload: str
|
|
1339
|
-
) -> Tuple[List[Dict[str, Any]], int, ManagedJobQueueResultType
|
|
1368
|
+
) -> Tuple[List[Dict[str, Any]], int, ManagedJobQueueResultType, int, Dict[
|
|
1369
|
+
str, int]]:
|
|
1340
1370
|
"""Load job queue from json string."""
|
|
1341
1371
|
result = message_utils.decode_payload(payload)
|
|
1342
1372
|
result_type = ManagedJobQueueResultType.DICT
|
|
1373
|
+
status_counts = {}
|
|
1343
1374
|
if isinstance(result, dict):
|
|
1344
1375
|
jobs = result['jobs']
|
|
1345
1376
|
total = result['total']
|
|
1377
|
+
status_counts = result.get('status_counts', {})
|
|
1378
|
+
total_no_filter = result.get('total_no_filter', total)
|
|
1346
1379
|
else:
|
|
1347
1380
|
jobs = result
|
|
1348
1381
|
total = len(jobs)
|
|
1382
|
+
total_no_filter = total
|
|
1349
1383
|
result_type = ManagedJobQueueResultType.LIST
|
|
1350
1384
|
|
|
1351
1385
|
for job in jobs:
|
|
@@ -1355,7 +1389,7 @@ def load_managed_job_queue(
|
|
|
1355
1389
|
# TODO(cooperc): Remove check before 0.12.0.
|
|
1356
1390
|
user = global_user_state.get_user(job['user_hash'])
|
|
1357
1391
|
job['user_name'] = user.name if user is not None else None
|
|
1358
|
-
return jobs, total, result_type
|
|
1392
|
+
return jobs, total, result_type, total_no_filter, status_counts
|
|
1359
1393
|
|
|
1360
1394
|
|
|
1361
1395
|
def _get_job_status_from_tasks(
|
|
@@ -1713,6 +1747,7 @@ class ManagedJobCodeGen:
|
|
|
1713
1747
|
page: Optional[int] = None,
|
|
1714
1748
|
limit: Optional[int] = None,
|
|
1715
1749
|
user_hashes: Optional[List[Optional[str]]] = None,
|
|
1750
|
+
statuses: Optional[List[str]] = None,
|
|
1716
1751
|
) -> str:
|
|
1717
1752
|
code = textwrap.dedent(f"""\
|
|
1718
1753
|
if managed_job_version < 9:
|
|
@@ -1720,7 +1755,7 @@ class ManagedJobCodeGen:
|
|
|
1720
1755
|
# before #6652.
|
|
1721
1756
|
# TODO(hailong): Remove compatibility before 0.12.0
|
|
1722
1757
|
job_table = utils.dump_managed_job_queue()
|
|
1723
|
-
|
|
1758
|
+
elif managed_job_version < 10:
|
|
1724
1759
|
job_table = utils.dump_managed_job_queue(
|
|
1725
1760
|
skip_finished={skip_finished},
|
|
1726
1761
|
accessible_workspaces={accessible_workspaces!r},
|
|
@@ -1731,6 +1766,18 @@ class ManagedJobCodeGen:
|
|
|
1731
1766
|
page={page!r},
|
|
1732
1767
|
limit={limit!r},
|
|
1733
1768
|
user_hashes={user_hashes!r})
|
|
1769
|
+
else:
|
|
1770
|
+
job_table = utils.dump_managed_job_queue(
|
|
1771
|
+
skip_finished={skip_finished},
|
|
1772
|
+
accessible_workspaces={accessible_workspaces!r},
|
|
1773
|
+
job_ids={job_ids!r},
|
|
1774
|
+
workspace_match={workspace_match!r},
|
|
1775
|
+
name_match={name_match!r},
|
|
1776
|
+
pool_match={pool_match!r},
|
|
1777
|
+
page={page!r},
|
|
1778
|
+
limit={limit!r},
|
|
1779
|
+
user_hashes={user_hashes!r},
|
|
1780
|
+
statuses={statuses!r})
|
|
1734
1781
|
print(job_table, flush=True)
|
|
1735
1782
|
""")
|
|
1736
1783
|
return cls._build(code)
|
sky/models.py
CHANGED