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.

Files changed (73) hide show
  1. sky/__init__.py +5 -3
  2. sky/backends/cloud_vm_ray_backend.py +6 -13
  3. sky/backends/wheel_utils.py +2 -1
  4. sky/catalog/data_fetchers/fetch_aws.py +2 -0
  5. sky/client/cli/command.py +20 -16
  6. sky/core.py +1 -1
  7. sky/dashboard/out/404.html +1 -1
  8. sky/dashboard/out/_next/static/{D7_ocVBIBwyxtvXYWggqV → 8ZscIHnvBWz3AXkxsJL6H}/_buildManifest.js +1 -1
  9. sky/dashboard/out/_next/static/chunks/3015-bf218e4973bf5c8f.js +1 -0
  10. sky/dashboard/out/_next/static/chunks/{8969-6cb1af4ec7fb1e19.js → 8969-23c8fbdb8b397d59.js} +1 -1
  11. sky/dashboard/out/_next/static/chunks/{webpack-a46c8b62df807ec1.js → webpack-008593a02784a2df.js} +1 -1
  12. sky/dashboard/out/clusters/[cluster]/[job].html +1 -1
  13. sky/dashboard/out/clusters/[cluster].html +1 -1
  14. sky/dashboard/out/clusters.html +1 -1
  15. sky/dashboard/out/config.html +1 -1
  16. sky/dashboard/out/index.html +1 -1
  17. sky/dashboard/out/infra/[context].html +1 -1
  18. sky/dashboard/out/infra.html +1 -1
  19. sky/dashboard/out/jobs/[job].html +1 -1
  20. sky/dashboard/out/jobs/pools/[pool].html +1 -1
  21. sky/dashboard/out/jobs.html +1 -1
  22. sky/dashboard/out/users.html +1 -1
  23. sky/dashboard/out/volumes.html +1 -1
  24. sky/dashboard/out/workspace/new.html +1 -1
  25. sky/dashboard/out/workspaces/[name].html +1 -1
  26. sky/dashboard/out/workspaces.html +1 -1
  27. sky/exceptions.py +6 -1
  28. sky/global_user_state.py +18 -11
  29. sky/jobs/constants.py +1 -1
  30. sky/jobs/server/core.py +43 -34
  31. sky/jobs/server/utils.py +2 -1
  32. sky/jobs/utils.py +56 -9
  33. sky/models.py +1 -0
  34. sky/provision/aws/config.py +11 -11
  35. sky/provision/aws/instance.py +30 -27
  36. sky/provision/do/utils.py +2 -2
  37. sky/provision/kubernetes/network_utils.py +3 -3
  38. sky/provision/kubernetes/utils.py +2 -2
  39. sky/provision/kubernetes/volume.py +2 -0
  40. sky/provision/provisioner.py +10 -6
  41. sky/serve/replica_managers.py +7 -0
  42. sky/serve/server/impl.py +1 -1
  43. sky/server/requests/payloads.py +2 -0
  44. sky/server/requests/serializers/encoders.py +29 -5
  45. sky/server/server.py +37 -1
  46. sky/setup_files/MANIFEST.in +1 -0
  47. sky/setup_files/dependencies.py +17 -11
  48. sky/skylet/ray_patches/__init__.py +18 -4
  49. sky/skylet/ray_patches/autoscaler.py.diff +18 -0
  50. sky/skylet/ray_patches/cli.py.diff +19 -0
  51. sky/skylet/ray_patches/command_runner.py.diff +17 -0
  52. sky/skylet/ray_patches/log_monitor.py.diff +20 -0
  53. sky/skylet/ray_patches/resource_demand_scheduler.py.diff +32 -0
  54. sky/skylet/ray_patches/updater.py.diff +18 -0
  55. sky/skylet/ray_patches/worker.py.diff +41 -0
  56. sky/utils/common.py +27 -7
  57. sky/utils/common_utils.py +13 -9
  58. sky/utils/directory_utils.py +12 -0
  59. sky/utils/env_options.py +3 -0
  60. sky/utils/kubernetes/gpu_labeler.py +3 -3
  61. sky/utils/schemas.py +1 -0
  62. sky/utils/serialize_utils.py +16 -0
  63. sky/volumes/client/sdk.py +10 -7
  64. sky/volumes/server/core.py +12 -3
  65. sky/volumes/volume.py +17 -3
  66. {skypilot_nightly-1.0.0.dev20250818.dist-info → skypilot_nightly-1.0.0.dev20250820.dist-info}/METADATA +21 -13
  67. {skypilot_nightly-1.0.0.dev20250818.dist-info → skypilot_nightly-1.0.0.dev20250820.dist-info}/RECORD +72 -63
  68. sky/dashboard/out/_next/static/chunks/3015-471d67c9302d4027.js +0 -1
  69. /sky/dashboard/out/_next/static/{D7_ocVBIBwyxtvXYWggqV → 8ZscIHnvBWz3AXkxsJL6H}/_ssgManifest.js +0 -0
  70. {skypilot_nightly-1.0.0.dev20250818.dist-info → skypilot_nightly-1.0.0.dev20250820.dist-info}/WHEEL +0 -0
  71. {skypilot_nightly-1.0.0.dev20250818.dist-info → skypilot_nightly-1.0.0.dev20250820.dist-info}/entry_points.txt +0 -0
  72. {skypilot_nightly-1.0.0.dev20250818.dist-info → skypilot_nightly-1.0.0.dev20250820.dist-info}/licenses/LICENSE +0 -0
  73. {skypilot_nightly-1.0.0.dev20250818.dist-info → skypilot_nightly-1.0.0.dev20250820.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-a46c8b62df807ec1.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/D7_ocVBIBwyxtvXYWggqV/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/D7_ocVBIBwyxtvXYWggqV/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/","query":{},"buildId":"D7_ocVBIBwyxtvXYWggqV","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
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-a46c8b62df807ec1.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/D7_ocVBIBwyxtvXYWggqV/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/D7_ocVBIBwyxtvXYWggqV/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/infra/[context]","query":{},"buildId":"D7_ocVBIBwyxtvXYWggqV","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
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>
@@ -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-a46c8b62df807ec1.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/D7_ocVBIBwyxtvXYWggqV/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/D7_ocVBIBwyxtvXYWggqV/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/infra","query":{},"buildId":"D7_ocVBIBwyxtvXYWggqV","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
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-a46c8b62df807ec1.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-6cb1af4ec7fb1e19.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/D7_ocVBIBwyxtvXYWggqV/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/D7_ocVBIBwyxtvXYWggqV/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/jobs/[job]","query":{},"buildId":"D7_ocVBIBwyxtvXYWggqV","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
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-a46c8b62df807ec1.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-6cb1af4ec7fb1e19.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/jobs/pools/%5Bpool%5D-7d4182df6625fe10.js" defer=""></script><script src="/dashboard/_next/static/D7_ocVBIBwyxtvXYWggqV/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/D7_ocVBIBwyxtvXYWggqV/_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":"D7_ocVBIBwyxtvXYWggqV","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
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>
@@ -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-a46c8b62df807ec1.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/D7_ocVBIBwyxtvXYWggqV/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/D7_ocVBIBwyxtvXYWggqV/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/jobs","query":{},"buildId":"D7_ocVBIBwyxtvXYWggqV","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
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>
@@ -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-a46c8b62df807ec1.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/D7_ocVBIBwyxtvXYWggqV/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/D7_ocVBIBwyxtvXYWggqV/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/users","query":{},"buildId":"D7_ocVBIBwyxtvXYWggqV","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
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>
@@ -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-a46c8b62df807ec1.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/D7_ocVBIBwyxtvXYWggqV/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/D7_ocVBIBwyxtvXYWggqV/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/volumes","query":{},"buildId":"D7_ocVBIBwyxtvXYWggqV","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
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-a46c8b62df807ec1.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/D7_ocVBIBwyxtvXYWggqV/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/D7_ocVBIBwyxtvXYWggqV/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/workspace/new","query":{},"buildId":"D7_ocVBIBwyxtvXYWggqV","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
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-a46c8b62df807ec1.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-6cb1af4ec7fb1e19.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-471d67c9302d4027.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/D7_ocVBIBwyxtvXYWggqV/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/D7_ocVBIBwyxtvXYWggqV/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/workspaces/[name]","query":{},"buildId":"D7_ocVBIBwyxtvXYWggqV","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
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-a46c8b62df807ec1.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/D7_ocVBIBwyxtvXYWggqV/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/D7_ocVBIBwyxtvXYWggqV/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/workspaces","query":{},"buildId":"D7_ocVBIBwyxtvXYWggqV","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
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
- if 'UNIQUE constraint failed' in str(e):
739
- # This can happen if the cluster event is added twice.
740
- # We can ignore this error unless the caller requests
741
- # to expose the error.
742
- if expose_duplicate_error:
743
- raise db_utils.UniqueConstraintViolationError(
744
- value=reason, message=str(e))
745
- else:
746
- pass
747
- else:
748
- raise e
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 = 9
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
- ) -> Tuple[List[Dict[str, Any]], int]:
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
- 'job_id': int,
600
- 'job_name': str,
601
- 'resources': str,
602
- 'submitted_at': (float) timestamp of submission,
603
- 'end_at': (float) timestamp of end,
604
- 'job_duration': (float) duration in seconds,
605
- 'recovery_count': (int) Number of retries,
606
- 'status': (sky.jobs.ManagedJobStatus) of the job,
607
- 'cluster_resources': (str) resources of the cluster,
608
- 'region': (str) region of the cluster,
609
- 'user_name': (Optional[str]) job creator's user name,
610
- 'user_hash': (str) job creator's user hash,
611
- 'task_id': (int), set to 0 (except in pipelines, which may have multiple tasks), # pylint: disable=line-too-long
612
- 'task_name': (str), same as job_name (except in pipelines, which may have multiple tasks), # pylint: disable=line-too-long
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 = managed_job_utils.load_managed_job_queue(
668
- job_table_payload)
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
- return managed_job_utils.filter_jobs(jobs,
706
- workspace_match,
707
- name_match,
708
- pool_match,
709
- page=page,
710
- limit=limit,
711
- user_match=user_match,
712
- enable_user_match=True)
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(job_table_payload)
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, workspace_match, name_match, pool_match,
1187
- page, limit)
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({'jobs': jobs, 'total': total})
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
- ) -> Tuple[List[Dict[str, Any]], int]:
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 and total number of 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
- else:
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
@@ -108,3 +108,4 @@ class VolumeConfig(pydantic.BaseModel):
108
108
  name_on_cloud: str
109
109
  size: Optional[str]
110
110
  config: Dict[str, Any] = {}
111
+ labels: Optional[Dict[str, str]] = None