skypilot-nightly 1.0.0.dev20250806__py3-none-any.whl → 1.0.0.dev20250808__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of skypilot-nightly might be problematic. Click here for more details.

Files changed (137) hide show
  1. sky/__init__.py +2 -2
  2. sky/backends/backend_utils.py +20 -1
  3. sky/backends/cloud_vm_ray_backend.py +42 -6
  4. sky/check.py +11 -1
  5. sky/client/cli/command.py +248 -119
  6. sky/client/sdk.py +146 -66
  7. sky/client/sdk_async.py +5 -1
  8. sky/core.py +5 -2
  9. sky/dashboard/out/404.html +1 -1
  10. sky/dashboard/out/_next/static/-DXZksWqf2waNHeU9YTQe/_buildManifest.js +1 -0
  11. sky/dashboard/out/_next/static/chunks/1141-a8a8f1adba34c892.js +11 -0
  12. sky/dashboard/out/_next/static/chunks/1871-980a395e92633a5c.js +6 -0
  13. sky/dashboard/out/_next/static/chunks/3785.6003d293cb83eab4.js +1 -0
  14. sky/dashboard/out/_next/static/chunks/3850-ff4a9a69d978632b.js +1 -0
  15. sky/dashboard/out/_next/static/chunks/4725.29550342bd53afd8.js +1 -0
  16. sky/dashboard/out/_next/static/chunks/{4937.d6bf67771e353356.js → 4937.a2baa2df5572a276.js} +1 -1
  17. sky/dashboard/out/_next/static/chunks/6130-2be46d70a38f1e82.js +1 -0
  18. sky/dashboard/out/_next/static/chunks/6601-06114c982db410b6.js +1 -0
  19. sky/dashboard/out/_next/static/chunks/{691.6d99cbfba347cebf.js → 691.5eeedf82cc243343.js} +1 -1
  20. sky/dashboard/out/_next/static/chunks/6989-6129c1cfbcf51063.js +1 -0
  21. sky/dashboard/out/_next/static/chunks/6990-0f886f16e0d55ff8.js +1 -0
  22. sky/dashboard/out/_next/static/chunks/8056-34d27f51e6d1c631.js +1 -0
  23. sky/dashboard/out/_next/static/chunks/8252.62b0d23aed618bb2.js +16 -0
  24. sky/dashboard/out/_next/static/chunks/8969-c9686994ddafcf01.js +1 -0
  25. sky/dashboard/out/_next/static/chunks/9025.a1bef12d672bb66d.js +6 -0
  26. sky/dashboard/out/_next/static/chunks/9159-11421c0f2909236f.js +1 -0
  27. sky/dashboard/out/_next/static/chunks/9360.85b0b1b4054574dd.js +31 -0
  28. sky/dashboard/out/_next/static/chunks/9666.cd4273f2a5c5802c.js +1 -0
  29. sky/dashboard/out/_next/static/chunks/{9847.4c46c5e229c78704.js → 9847.757720f3b40c0aa5.js} +1 -1
  30. sky/dashboard/out/_next/static/chunks/pages/{_app-2a43ea3241bbdacd.js → _app-491a4d699d95e808.js} +1 -1
  31. sky/dashboard/out/_next/static/chunks/pages/clusters/[cluster]/[job]-ae17cec0fc6483d9.js +11 -0
  32. sky/dashboard/out/_next/static/chunks/pages/clusters/[cluster]-155d477a6c3e04e2.js +1 -0
  33. sky/dashboard/out/_next/static/chunks/pages/{clusters-47f1ddae13a2f8e4.js → clusters-b30460f683e6ba96.js} +1 -1
  34. sky/dashboard/out/_next/static/chunks/pages/config-dfb9bf07b13045f4.js +1 -0
  35. sky/dashboard/out/_next/static/chunks/pages/infra/{[context]-2a44e70b500b6b70.js → [context]-13d53fffc03ccb52.js} +1 -1
  36. sky/dashboard/out/_next/static/chunks/pages/{infra-22faac9325016d83.js → infra-fc9222e26c8e2f0d.js} +1 -1
  37. sky/dashboard/out/_next/static/chunks/pages/jobs/[job]-154f55cf8af55be5.js +11 -0
  38. sky/dashboard/out/_next/static/chunks/pages/jobs/pools/[pool]-f5ccf5d39d87aebe.js +21 -0
  39. sky/dashboard/out/_next/static/chunks/pages/jobs-cdc60fb5d371e16a.js +1 -0
  40. sky/dashboard/out/_next/static/chunks/pages/{users-b90c865a690bfe84.js → users-7ed36e44e779d5c7.js} +1 -1
  41. sky/dashboard/out/_next/static/chunks/pages/{volumes-7af733f5d7b6ed1c.js → volumes-c9695d657f78b5dc.js} +1 -1
  42. sky/dashboard/out/_next/static/chunks/pages/workspace/new-3f88a1c7e86a3f86.js +1 -0
  43. sky/dashboard/out/_next/static/chunks/pages/workspaces/[name]-f72f73bcef9541dc.js +1 -0
  44. sky/dashboard/out/_next/static/chunks/pages/workspaces-8f67be60165724cc.js +1 -0
  45. sky/dashboard/out/_next/static/chunks/webpack-339efec49c0cc7d0.js +1 -0
  46. sky/dashboard/out/_next/static/css/4614e06482d7309e.css +3 -0
  47. sky/dashboard/out/clusters/[cluster]/[job].html +1 -1
  48. sky/dashboard/out/clusters/[cluster].html +1 -1
  49. sky/dashboard/out/clusters.html +1 -1
  50. sky/dashboard/out/config.html +1 -1
  51. sky/dashboard/out/index.html +1 -1
  52. sky/dashboard/out/infra/[context].html +1 -1
  53. sky/dashboard/out/infra.html +1 -1
  54. sky/dashboard/out/jobs/[job].html +1 -1
  55. sky/dashboard/out/jobs/pools/[pool].html +1 -0
  56. sky/dashboard/out/jobs.html +1 -1
  57. sky/dashboard/out/users.html +1 -1
  58. sky/dashboard/out/volumes.html +1 -1
  59. sky/dashboard/out/workspace/new.html +1 -1
  60. sky/dashboard/out/workspaces/[name].html +1 -1
  61. sky/dashboard/out/workspaces.html +1 -1
  62. sky/execution.py +6 -4
  63. sky/global_user_state.py +22 -3
  64. sky/jobs/__init__.py +2 -0
  65. sky/jobs/client/sdk.py +67 -19
  66. sky/jobs/controller.py +2 -1
  67. sky/jobs/server/core.py +48 -1
  68. sky/jobs/server/server.py +52 -3
  69. sky/jobs/state.py +5 -1
  70. sky/schemas/db/global_user_state/002_add_workspace_to_cluster_history.py +35 -0
  71. sky/schemas/db/global_user_state/003_fix_initial_revision.py +61 -0
  72. sky/schemas/db/global_user_state/004_is_managed.py +34 -0
  73. sky/schemas/db/serve_state/001_initial_schema.py +67 -0
  74. sky/schemas/db/spot_jobs/003_pool_hash.py +34 -0
  75. sky/serve/client/impl.py +93 -6
  76. sky/serve/client/sdk.py +22 -53
  77. sky/serve/constants.py +2 -1
  78. sky/serve/controller.py +4 -2
  79. sky/serve/serve_state.py +444 -324
  80. sky/serve/serve_utils.py +77 -46
  81. sky/serve/server/core.py +13 -197
  82. sky/serve/server/impl.py +239 -2
  83. sky/serve/service.py +8 -3
  84. sky/server/common.py +18 -7
  85. sky/server/constants.py +1 -1
  86. sky/server/requests/executor.py +5 -3
  87. sky/server/requests/payloads.py +19 -0
  88. sky/setup_files/alembic.ini +4 -0
  89. sky/task.py +18 -11
  90. sky/templates/kubernetes-ray.yml.j2 +5 -0
  91. sky/templates/sky-serve-controller.yaml.j2 +1 -0
  92. sky/usage/usage_lib.py +8 -6
  93. sky/utils/annotations.py +8 -3
  94. sky/utils/cli_utils/status_utils.py +1 -1
  95. sky/utils/common_utils.py +11 -1
  96. sky/utils/db/db_utils.py +31 -0
  97. sky/utils/db/migration_utils.py +6 -2
  98. sky/utils/kubernetes/deploy_remote_cluster.py +3 -1
  99. sky/utils/resource_checker.py +162 -21
  100. sky/volumes/client/sdk.py +4 -4
  101. sky/workspaces/core.py +210 -6
  102. {skypilot_nightly-1.0.0.dev20250806.dist-info → skypilot_nightly-1.0.0.dev20250808.dist-info}/METADATA +19 -14
  103. {skypilot_nightly-1.0.0.dev20250806.dist-info → skypilot_nightly-1.0.0.dev20250808.dist-info}/RECORD +109 -103
  104. sky/client/sdk.pyi +0 -301
  105. sky/dashboard/out/_next/static/Gelsd19kVxXcX7aQQGsGu/_buildManifest.js +0 -1
  106. sky/dashboard/out/_next/static/chunks/1043-75af48ca5d5aaf57.js +0 -1
  107. sky/dashboard/out/_next/static/chunks/1141-8678a9102cc5f67e.js +0 -11
  108. sky/dashboard/out/_next/static/chunks/1664-22b00e32c9ff96a4.js +0 -1
  109. sky/dashboard/out/_next/static/chunks/1871-ced1c14230cad6e1.js +0 -6
  110. sky/dashboard/out/_next/static/chunks/2003.f90b06bb1f914295.js +0 -1
  111. sky/dashboard/out/_next/static/chunks/2350.fab69e61bac57b23.js +0 -1
  112. sky/dashboard/out/_next/static/chunks/2622-951867535095b0eb.js +0 -1
  113. sky/dashboard/out/_next/static/chunks/3785.0a173cd4393f0fef.js +0 -1
  114. sky/dashboard/out/_next/static/chunks/4725.42f21f250f91f65b.js +0 -1
  115. sky/dashboard/out/_next/static/chunks/4869.18e6a4361a380763.js +0 -16
  116. sky/dashboard/out/_next/static/chunks/5230-f3bb2663e442e86c.js +0 -1
  117. sky/dashboard/out/_next/static/chunks/6601-2109d22e7861861c.js +0 -1
  118. sky/dashboard/out/_next/static/chunks/6990-08b2a1cae076a943.js +0 -1
  119. sky/dashboard/out/_next/static/chunks/8969-9a8cca241b30db83.js +0 -1
  120. sky/dashboard/out/_next/static/chunks/9025.99f29acb7617963e.js +0 -6
  121. sky/dashboard/out/_next/static/chunks/938-bda2685db5eae6cf.js +0 -1
  122. sky/dashboard/out/_next/static/chunks/pages/clusters/[cluster]/[job]-7cb24da04ca00956.js +0 -11
  123. sky/dashboard/out/_next/static/chunks/pages/clusters/[cluster]-1e95993124dbfc57.js +0 -1
  124. sky/dashboard/out/_next/static/chunks/pages/config-d56e64f30db7b42e.js +0 -1
  125. sky/dashboard/out/_next/static/chunks/pages/jobs/[job]-90693cb88b5599a7.js +0 -11
  126. sky/dashboard/out/_next/static/chunks/pages/jobs-ab318e52eb4424a7.js +0 -1
  127. sky/dashboard/out/_next/static/chunks/pages/workspace/new-92f741084a89e27b.js +0 -1
  128. sky/dashboard/out/_next/static/chunks/pages/workspaces/[name]-35e0de5bca55e594.js +0 -1
  129. sky/dashboard/out/_next/static/chunks/pages/workspaces-062525fb5462acb6.js +0 -1
  130. sky/dashboard/out/_next/static/chunks/webpack-387626669badf82e.js +0 -1
  131. sky/dashboard/out/_next/static/css/b3227360726f12eb.css +0 -3
  132. /sky/dashboard/out/_next/static/{Gelsd19kVxXcX7aQQGsGu → -DXZksWqf2waNHeU9YTQe}/_ssgManifest.js +0 -0
  133. /sky/dashboard/out/_next/static/chunks/{6135-2d7ed3350659d073.js → 6135-85426374db04811e.js} +0 -0
  134. {skypilot_nightly-1.0.0.dev20250806.dist-info → skypilot_nightly-1.0.0.dev20250808.dist-info}/WHEEL +0 -0
  135. {skypilot_nightly-1.0.0.dev20250806.dist-info → skypilot_nightly-1.0.0.dev20250808.dist-info}/entry_points.txt +0 -0
  136. {skypilot_nightly-1.0.0.dev20250806.dist-info → skypilot_nightly-1.0.0.dev20250808.dist-info}/licenses/LICENSE +0 -0
  137. {skypilot_nightly-1.0.0.dev20250806.dist-info → skypilot_nightly-1.0.0.dev20250808.dist-info}/top_level.txt +0 -0
@@ -1 +1 @@
1
- <!DOCTYPE html><html><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><meta name="next-head-count" content="2"/><link rel="preload" href="/dashboard/_next/static/css/b3227360726f12eb.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/b3227360726f12eb.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-387626669badf82e.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-2a43ea3241bbdacd.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/clusters-47f1ddae13a2f8e4.js" defer=""></script><script src="/dashboard/_next/static/Gelsd19kVxXcX7aQQGsGu/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/Gelsd19kVxXcX7aQQGsGu/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/clusters","query":{},"buildId":"Gelsd19kVxXcX7aQQGsGu","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-339efec49c0cc7d0.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-cf60a09ccd051a10.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-f15ccb73239a3bf1.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-491a4d699d95e808.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/clusters-b30460f683e6ba96.js" defer=""></script><script src="/dashboard/_next/static/-DXZksWqf2waNHeU9YTQe/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/-DXZksWqf2waNHeU9YTQe/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/clusters","query":{},"buildId":"-DXZksWqf2waNHeU9YTQe","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
@@ -1 +1 @@
1
- <!DOCTYPE html><html><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><meta name="next-head-count" content="2"/><link rel="preload" href="/dashboard/_next/static/css/b3227360726f12eb.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/b3227360726f12eb.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-387626669badf82e.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-2a43ea3241bbdacd.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/config-d56e64f30db7b42e.js" defer=""></script><script src="/dashboard/_next/static/Gelsd19kVxXcX7aQQGsGu/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/Gelsd19kVxXcX7aQQGsGu/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/config","query":{},"buildId":"Gelsd19kVxXcX7aQQGsGu","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-339efec49c0cc7d0.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-cf60a09ccd051a10.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-f15ccb73239a3bf1.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-491a4d699d95e808.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/config-dfb9bf07b13045f4.js" defer=""></script><script src="/dashboard/_next/static/-DXZksWqf2waNHeU9YTQe/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/-DXZksWqf2waNHeU9YTQe/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/config","query":{},"buildId":"-DXZksWqf2waNHeU9YTQe","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
@@ -1 +1 @@
1
- <!DOCTYPE html><html><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><meta name="next-head-count" content="2"/><link rel="preload" href="/dashboard/_next/static/css/b3227360726f12eb.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/b3227360726f12eb.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-387626669badf82e.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-2a43ea3241bbdacd.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/index-444f1804401f04ea.js" defer=""></script><script src="/dashboard/_next/static/Gelsd19kVxXcX7aQQGsGu/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/Gelsd19kVxXcX7aQQGsGu/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/","query":{},"buildId":"Gelsd19kVxXcX7aQQGsGu","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-339efec49c0cc7d0.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-cf60a09ccd051a10.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-f15ccb73239a3bf1.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-491a4d699d95e808.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/index-444f1804401f04ea.js" defer=""></script><script src="/dashboard/_next/static/-DXZksWqf2waNHeU9YTQe/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/-DXZksWqf2waNHeU9YTQe/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/","query":{},"buildId":"-DXZksWqf2waNHeU9YTQe","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
@@ -1 +1 @@
1
- <!DOCTYPE html><html><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><meta name="next-head-count" content="2"/><link rel="preload" href="/dashboard/_next/static/css/b3227360726f12eb.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/b3227360726f12eb.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-387626669badf82e.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-2a43ea3241bbdacd.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/infra/%5Bcontext%5D-2a44e70b500b6b70.js" defer=""></script><script src="/dashboard/_next/static/Gelsd19kVxXcX7aQQGsGu/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/Gelsd19kVxXcX7aQQGsGu/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/infra/[context]","query":{},"buildId":"Gelsd19kVxXcX7aQQGsGu","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-339efec49c0cc7d0.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-cf60a09ccd051a10.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-f15ccb73239a3bf1.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-491a4d699d95e808.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/infra/%5Bcontext%5D-13d53fffc03ccb52.js" defer=""></script><script src="/dashboard/_next/static/-DXZksWqf2waNHeU9YTQe/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/-DXZksWqf2waNHeU9YTQe/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/infra/[context]","query":{},"buildId":"-DXZksWqf2waNHeU9YTQe","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
@@ -1 +1 @@
1
- <!DOCTYPE html><html><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><meta name="next-head-count" content="2"/><link rel="preload" href="/dashboard/_next/static/css/b3227360726f12eb.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/b3227360726f12eb.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-387626669badf82e.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-2a43ea3241bbdacd.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/infra-22faac9325016d83.js" defer=""></script><script src="/dashboard/_next/static/Gelsd19kVxXcX7aQQGsGu/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/Gelsd19kVxXcX7aQQGsGu/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/infra","query":{},"buildId":"Gelsd19kVxXcX7aQQGsGu","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-339efec49c0cc7d0.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-cf60a09ccd051a10.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-f15ccb73239a3bf1.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-491a4d699d95e808.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/infra-fc9222e26c8e2f0d.js" defer=""></script><script src="/dashboard/_next/static/-DXZksWqf2waNHeU9YTQe/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/-DXZksWqf2waNHeU9YTQe/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/infra","query":{},"buildId":"-DXZksWqf2waNHeU9YTQe","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
@@ -1 +1 @@
1
- <!DOCTYPE html><html><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><meta name="next-head-count" content="2"/><link rel="preload" href="/dashboard/_next/static/css/b3227360726f12eb.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/b3227360726f12eb.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-387626669badf82e.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-2a43ea3241bbdacd.js" defer=""></script><script src="/dashboard/_next/static/chunks/616-3d59f75e2ccf9321.js" defer=""></script><script src="/dashboard/_next/static/chunks/5230-f3bb2663e442e86c.js" defer=""></script><script src="/dashboard/_next/static/chunks/5739-d67458fcb1386c92.js" defer=""></script><script src="/dashboard/_next/static/chunks/1664-22b00e32c9ff96a4.js" defer=""></script><script src="/dashboard/_next/static/chunks/7411-b15471acd2cba716.js" defer=""></script><script src="/dashboard/_next/static/chunks/1272-1ef0bf0237faccdb.js" defer=""></script><script src="/dashboard/_next/static/chunks/6212-7bd06f60ba693125.js" defer=""></script><script src="/dashboard/_next/static/chunks/2622-951867535095b0eb.js" defer=""></script><script src="/dashboard/_next/static/chunks/6135-2d7ed3350659d073.js" defer=""></script><script src="/dashboard/_next/static/chunks/8969-9a8cca241b30db83.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/jobs/%5Bjob%5D-90693cb88b5599a7.js" defer=""></script><script src="/dashboard/_next/static/Gelsd19kVxXcX7aQQGsGu/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/Gelsd19kVxXcX7aQQGsGu/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/jobs/[job]","query":{},"buildId":"Gelsd19kVxXcX7aQQGsGu","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-339efec49c0cc7d0.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-cf60a09ccd051a10.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-f15ccb73239a3bf1.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-491a4d699d95e808.js" defer=""></script><script src="/dashboard/_next/static/chunks/616-3d59f75e2ccf9321.js" defer=""></script><script src="/dashboard/_next/static/chunks/6130-2be46d70a38f1e82.js" defer=""></script><script src="/dashboard/_next/static/chunks/5739-d67458fcb1386c92.js" defer=""></script><script src="/dashboard/_next/static/chunks/7411-b15471acd2cba716.js" defer=""></script><script src="/dashboard/_next/static/chunks/1272-1ef0bf0237faccdb.js" defer=""></script><script src="/dashboard/_next/static/chunks/6212-7bd06f60ba693125.js" defer=""></script><script src="/dashboard/_next/static/chunks/6989-6129c1cfbcf51063.js" defer=""></script><script src="/dashboard/_next/static/chunks/3850-ff4a9a69d978632b.js" defer=""></script><script src="/dashboard/_next/static/chunks/8969-c9686994ddafcf01.js" defer=""></script><script src="/dashboard/_next/static/chunks/6135-85426374db04811e.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/jobs/%5Bjob%5D-154f55cf8af55be5.js" defer=""></script><script src="/dashboard/_next/static/-DXZksWqf2waNHeU9YTQe/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/-DXZksWqf2waNHeU9YTQe/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/jobs/[job]","query":{},"buildId":"-DXZksWqf2waNHeU9YTQe","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
@@ -0,0 +1 @@
1
+ <!DOCTYPE html><html><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><meta name="next-head-count" content="2"/><link rel="preload" href="/dashboard/_next/static/css/4614e06482d7309e.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/4614e06482d7309e.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/dashboard/_next/static/chunks/polyfills-78c92fac7aa8fdd8.js"></script><script src="/dashboard/_next/static/chunks/webpack-339efec49c0cc7d0.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-cf60a09ccd051a10.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-f15ccb73239a3bf1.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-491a4d699d95e808.js" defer=""></script><script src="/dashboard/_next/static/chunks/616-3d59f75e2ccf9321.js" defer=""></script><script src="/dashboard/_next/static/chunks/6130-2be46d70a38f1e82.js" defer=""></script><script src="/dashboard/_next/static/chunks/5739-d67458fcb1386c92.js" defer=""></script><script src="/dashboard/_next/static/chunks/1272-1ef0bf0237faccdb.js" defer=""></script><script src="/dashboard/_next/static/chunks/6212-7bd06f60ba693125.js" defer=""></script><script src="/dashboard/_next/static/chunks/6989-6129c1cfbcf51063.js" defer=""></script><script src="/dashboard/_next/static/chunks/3850-ff4a9a69d978632b.js" defer=""></script><script src="/dashboard/_next/static/chunks/8969-c9686994ddafcf01.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/jobs/pools/%5Bpool%5D-f5ccf5d39d87aebe.js" defer=""></script><script src="/dashboard/_next/static/-DXZksWqf2waNHeU9YTQe/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/-DXZksWqf2waNHeU9YTQe/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/jobs/pools/[pool]","query":{},"buildId":"-DXZksWqf2waNHeU9YTQe","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
@@ -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/b3227360726f12eb.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/b3227360726f12eb.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-387626669badf82e.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-2a43ea3241bbdacd.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/jobs-ab318e52eb4424a7.js" defer=""></script><script src="/dashboard/_next/static/Gelsd19kVxXcX7aQQGsGu/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/Gelsd19kVxXcX7aQQGsGu/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/jobs","query":{},"buildId":"Gelsd19kVxXcX7aQQGsGu","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-339efec49c0cc7d0.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-cf60a09ccd051a10.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-f15ccb73239a3bf1.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-491a4d699d95e808.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/jobs-cdc60fb5d371e16a.js" defer=""></script><script src="/dashboard/_next/static/-DXZksWqf2waNHeU9YTQe/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/-DXZksWqf2waNHeU9YTQe/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/jobs","query":{},"buildId":"-DXZksWqf2waNHeU9YTQe","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
@@ -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/b3227360726f12eb.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/b3227360726f12eb.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-387626669badf82e.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-2a43ea3241bbdacd.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/users-b90c865a690bfe84.js" defer=""></script><script src="/dashboard/_next/static/Gelsd19kVxXcX7aQQGsGu/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/Gelsd19kVxXcX7aQQGsGu/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/users","query":{},"buildId":"Gelsd19kVxXcX7aQQGsGu","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-339efec49c0cc7d0.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-cf60a09ccd051a10.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-f15ccb73239a3bf1.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-491a4d699d95e808.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/users-7ed36e44e779d5c7.js" defer=""></script><script src="/dashboard/_next/static/-DXZksWqf2waNHeU9YTQe/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/-DXZksWqf2waNHeU9YTQe/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/users","query":{},"buildId":"-DXZksWqf2waNHeU9YTQe","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
@@ -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/b3227360726f12eb.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/b3227360726f12eb.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-387626669badf82e.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-2a43ea3241bbdacd.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/volumes-7af733f5d7b6ed1c.js" defer=""></script><script src="/dashboard/_next/static/Gelsd19kVxXcX7aQQGsGu/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/Gelsd19kVxXcX7aQQGsGu/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/volumes","query":{},"buildId":"Gelsd19kVxXcX7aQQGsGu","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-339efec49c0cc7d0.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-cf60a09ccd051a10.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-f15ccb73239a3bf1.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-491a4d699d95e808.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/volumes-c9695d657f78b5dc.js" defer=""></script><script src="/dashboard/_next/static/-DXZksWqf2waNHeU9YTQe/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/-DXZksWqf2waNHeU9YTQe/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/volumes","query":{},"buildId":"-DXZksWqf2waNHeU9YTQe","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
@@ -1 +1 @@
1
- <!DOCTYPE html><html><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><meta name="next-head-count" content="2"/><link rel="preload" href="/dashboard/_next/static/css/b3227360726f12eb.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/b3227360726f12eb.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-387626669badf82e.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-2a43ea3241bbdacd.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/workspace/new-92f741084a89e27b.js" defer=""></script><script src="/dashboard/_next/static/Gelsd19kVxXcX7aQQGsGu/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/Gelsd19kVxXcX7aQQGsGu/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/workspace/new","query":{},"buildId":"Gelsd19kVxXcX7aQQGsGu","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-339efec49c0cc7d0.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-cf60a09ccd051a10.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-f15ccb73239a3bf1.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-491a4d699d95e808.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/workspace/new-3f88a1c7e86a3f86.js" defer=""></script><script src="/dashboard/_next/static/-DXZksWqf2waNHeU9YTQe/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/-DXZksWqf2waNHeU9YTQe/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/workspace/new","query":{},"buildId":"-DXZksWqf2waNHeU9YTQe","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
@@ -1 +1 @@
1
- <!DOCTYPE html><html><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><meta name="next-head-count" content="2"/><link rel="preload" href="/dashboard/_next/static/css/b3227360726f12eb.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/b3227360726f12eb.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-387626669badf82e.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-2a43ea3241bbdacd.js" defer=""></script><script src="/dashboard/_next/static/chunks/616-3d59f75e2ccf9321.js" defer=""></script><script src="/dashboard/_next/static/chunks/5230-f3bb2663e442e86c.js" defer=""></script><script src="/dashboard/_next/static/chunks/5739-d67458fcb1386c92.js" defer=""></script><script src="/dashboard/_next/static/chunks/1664-22b00e32c9ff96a4.js" defer=""></script><script src="/dashboard/_next/static/chunks/7411-b15471acd2cba716.js" defer=""></script><script src="/dashboard/_next/static/chunks/1272-1ef0bf0237faccdb.js" defer=""></script><script src="/dashboard/_next/static/chunks/1559-6c00e20454194859.js" defer=""></script><script src="/dashboard/_next/static/chunks/2622-951867535095b0eb.js" defer=""></script><script src="/dashboard/_next/static/chunks/6135-2d7ed3350659d073.js" defer=""></script><script src="/dashboard/_next/static/chunks/6990-08b2a1cae076a943.js" defer=""></script><script src="/dashboard/_next/static/chunks/8969-9a8cca241b30db83.js" defer=""></script><script src="/dashboard/_next/static/chunks/1043-75af48ca5d5aaf57.js" defer=""></script><script src="/dashboard/_next/static/chunks/6601-2109d22e7861861c.js" defer=""></script><script src="/dashboard/_next/static/chunks/938-bda2685db5eae6cf.js" defer=""></script><script src="/dashboard/_next/static/chunks/1141-8678a9102cc5f67e.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/workspaces/%5Bname%5D-35e0de5bca55e594.js" defer=""></script><script src="/dashboard/_next/static/Gelsd19kVxXcX7aQQGsGu/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/Gelsd19kVxXcX7aQQGsGu/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/workspaces/[name]","query":{},"buildId":"Gelsd19kVxXcX7aQQGsGu","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-339efec49c0cc7d0.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-cf60a09ccd051a10.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-f15ccb73239a3bf1.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-491a4d699d95e808.js" defer=""></script><script src="/dashboard/_next/static/chunks/616-3d59f75e2ccf9321.js" defer=""></script><script src="/dashboard/_next/static/chunks/6130-2be46d70a38f1e82.js" defer=""></script><script src="/dashboard/_next/static/chunks/5739-d67458fcb1386c92.js" defer=""></script><script src="/dashboard/_next/static/chunks/7411-b15471acd2cba716.js" defer=""></script><script src="/dashboard/_next/static/chunks/1272-1ef0bf0237faccdb.js" defer=""></script><script src="/dashboard/_next/static/chunks/1559-6c00e20454194859.js" defer=""></script><script src="/dashboard/_next/static/chunks/6989-6129c1cfbcf51063.js" defer=""></script><script src="/dashboard/_next/static/chunks/3850-ff4a9a69d978632b.js" defer=""></script><script src="/dashboard/_next/static/chunks/8969-c9686994ddafcf01.js" defer=""></script><script src="/dashboard/_next/static/chunks/6990-0f886f16e0d55ff8.js" defer=""></script><script src="/dashboard/_next/static/chunks/8056-34d27f51e6d1c631.js" defer=""></script><script src="/dashboard/_next/static/chunks/6135-85426374db04811e.js" defer=""></script><script src="/dashboard/_next/static/chunks/6601-06114c982db410b6.js" defer=""></script><script src="/dashboard/_next/static/chunks/9159-11421c0f2909236f.js" defer=""></script><script src="/dashboard/_next/static/chunks/1141-a8a8f1adba34c892.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/workspaces/%5Bname%5D-f72f73bcef9541dc.js" defer=""></script><script src="/dashboard/_next/static/-DXZksWqf2waNHeU9YTQe/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/-DXZksWqf2waNHeU9YTQe/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/workspaces/[name]","query":{},"buildId":"-DXZksWqf2waNHeU9YTQe","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
@@ -1 +1 @@
1
- <!DOCTYPE html><html><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><meta name="next-head-count" content="2"/><link rel="preload" href="/dashboard/_next/static/css/b3227360726f12eb.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/b3227360726f12eb.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-387626669badf82e.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-2a43ea3241bbdacd.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/workspaces-062525fb5462acb6.js" defer=""></script><script src="/dashboard/_next/static/Gelsd19kVxXcX7aQQGsGu/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/Gelsd19kVxXcX7aQQGsGu/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/workspaces","query":{},"buildId":"Gelsd19kVxXcX7aQQGsGu","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-339efec49c0cc7d0.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-cf60a09ccd051a10.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-f15ccb73239a3bf1.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-491a4d699d95e808.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/workspaces-8f67be60165724cc.js" defer=""></script><script src="/dashboard/_next/static/-DXZksWqf2waNHeU9YTQe/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/-DXZksWqf2waNHeU9YTQe/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/workspaces","query":{},"buildId":"-DXZksWqf2waNHeU9YTQe","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
sky/execution.py CHANGED
@@ -353,12 +353,13 @@ def _execute_dag(
353
353
  task = _maybe_clone_disk_from_cluster(clone_disk_from, cluster_name,
354
354
  task)
355
355
 
356
+ is_managed = (_is_launched_by_jobs_controller or
357
+ _is_launched_by_sky_serve_controller)
358
+
356
359
  if not cluster_exists:
357
360
  # If spot is launched on serve or jobs controller, we don't need to
358
361
  # print out the hint.
359
- if (Stage.PROVISION in stages and task.use_spot and
360
- not _is_launched_by_jobs_controller and
361
- not _is_launched_by_sky_serve_controller):
362
+ if (Stage.PROVISION in stages and task.use_spot and not is_managed):
362
363
  yellow = colorama.Fore.YELLOW
363
364
  bold = colorama.Style.BRIGHT
364
365
  reset = colorama.Style.RESET_ALL
@@ -397,7 +398,8 @@ def _execute_dag(
397
398
  # That's because we want to do commands in task.setup and task.run again
398
399
  # after K8S pod recovers from a crash.
399
400
  # See `kubernetes-ray.yml.j2` for more details.
400
- dump_final_script=is_controller_high_availability_supported)
401
+ dump_final_script=is_controller_high_availability_supported,
402
+ is_managed=is_managed)
401
403
 
402
404
  if task.storage_mounts is not None:
403
405
  # Optimizer should eventually choose where to store bucket
sky/global_user_state.py CHANGED
@@ -100,6 +100,7 @@ cluster_table = sqlalchemy.Table(
100
100
  sqlalchemy.Column('last_creation_command',
101
101
  sqlalchemy.Text,
102
102
  server_default=None),
103
+ sqlalchemy.Column('is_managed', sqlalchemy.Integer, server_default='0'),
103
104
  )
104
105
 
105
106
  storage_table = sqlalchemy.Table(
@@ -158,6 +159,7 @@ cluster_history_table = sqlalchemy.Table(
158
159
  sqlalchemy.Column('last_creation_command',
159
160
  sqlalchemy.Text,
160
161
  server_default=None),
162
+ sqlalchemy.Column('workspace', sqlalchemy.Text, server_default=None),
161
163
  )
162
164
 
163
165
  ssh_key_table = sqlalchemy.Table(
@@ -427,7 +429,8 @@ def add_or_update_cluster(cluster_name: str,
427
429
  ready: bool,
428
430
  is_launch: bool = True,
429
431
  config_hash: Optional[str] = None,
430
- task_config: Optional[Dict[str, Any]] = None):
432
+ task_config: Optional[Dict[str, Any]] = None,
433
+ is_managed: bool = False):
431
434
  """Adds or updates cluster_name -> cluster_handle mapping.
432
435
 
433
436
  Args:
@@ -440,6 +443,8 @@ def add_or_update_cluster(cluster_name: str,
440
443
  and last_use will be updated. Otherwise, use the old value.
441
444
  config_hash: Configuration hash for the cluster.
442
445
  task_config: The config of the task being launched.
446
+ is_managed: Whether the cluster is launched by the
447
+ controller.
443
448
  """
444
449
  assert _SQLALCHEMY_ENGINE is not None
445
450
  # FIXME: launched_at will be changed when `sky launch -c` is called.
@@ -476,6 +481,8 @@ def add_or_update_cluster(cluster_name: str,
476
481
 
477
482
  user_hash = common_utils.get_current_user().id
478
483
  active_workspace = skypilot_config.get_active_workspace()
484
+ history_workspace = active_workspace
485
+ history_hash = user_hash
479
486
 
480
487
  conditional_values = {}
481
488
  if is_launch:
@@ -541,6 +548,7 @@ def add_or_update_cluster(cluster_name: str,
541
548
  cluster_hash=cluster_hash,
542
549
  # set storage_mounts_metadata to server default (null)
543
550
  status_updated_at=status_updated_at,
551
+ is_managed=int(is_managed),
544
552
  )
545
553
  do_update_stmt = insert_stmnt.on_conflict_do_update(
546
554
  index_elements=[cluster_table.c.name],
@@ -560,6 +568,10 @@ def add_or_update_cluster(cluster_name: str,
560
568
  # Modify cluster history table
561
569
  launched_nodes = getattr(cluster_handle, 'launched_nodes', None)
562
570
  launched_resources = getattr(cluster_handle, 'launched_resources', None)
571
+ if cluster_row and cluster_row.workspace:
572
+ history_workspace = cluster_row.workspace
573
+ if cluster_row and cluster_row.user_hash:
574
+ history_hash = cluster_row.user_hash
563
575
  creation_info = {}
564
576
  if conditional_values.get('last_creation_yaml') is not None:
565
577
  creation_info = {
@@ -577,6 +589,7 @@ def add_or_update_cluster(cluster_name: str,
577
589
  launched_resources=pickle.dumps(launched_resources),
578
590
  usage_intervals=pickle.dumps(usage_intervals),
579
591
  user_hash=user_hash,
592
+ workspace=history_workspace,
580
593
  **creation_info,
581
594
  )
582
595
  do_update_stmt = insert_stmnt.on_conflict_do_update(
@@ -590,7 +603,8 @@ def add_or_update_cluster(cluster_name: str,
590
603
  pickle.dumps(launched_resources),
591
604
  cluster_history_table.c.usage_intervals:
592
605
  pickle.dumps(usage_intervals),
593
- cluster_history_table.c.user_hash: user_hash,
606
+ cluster_history_table.c.user_hash: history_hash,
607
+ cluster_history_table.c.workspace: history_workspace,
594
608
  **creation_info,
595
609
  })
596
610
  session.execute(do_update_stmt)
@@ -956,6 +970,7 @@ def get_cluster_from_name(
956
970
  'workspace': row.workspace,
957
971
  'last_creation_yaml': row.last_creation_yaml,
958
972
  'last_creation_command': row.last_creation_command,
973
+ 'is_managed': bool(row.is_managed),
959
974
  }
960
975
 
961
976
  return record
@@ -994,6 +1009,7 @@ def get_clusters() -> List[Dict[str, Any]]:
994
1009
  'workspace': row.workspace,
995
1010
  'last_creation_yaml': row.last_creation_yaml,
996
1011
  'last_creation_command': row.last_creation_command,
1012
+ 'is_managed': bool(row.is_managed),
997
1013
  }
998
1014
 
999
1015
  records.append(record)
@@ -1026,6 +1042,7 @@ def get_clusters_from_history(
1026
1042
  cluster_history_table.c.user_hash,
1027
1043
  cluster_history_table.c.last_creation_yaml,
1028
1044
  cluster_history_table.c.last_creation_command,
1045
+ cluster_history_table.c.workspace.label('history_workspace'),
1029
1046
  cluster_table.c.status, cluster_table.c.workspace,
1030
1047
  cluster_table.c.status_updated_at).select_from(
1031
1048
  cluster_history_table.join(cluster_table,
@@ -1096,6 +1113,8 @@ def get_clusters_from_history(
1096
1113
  # Get user name from user hash
1097
1114
  user = get_user(user_hash)
1098
1115
  user_name = user.name if user is not None else None
1116
+ workspace = (row.history_workspace
1117
+ if row.history_workspace else row.workspace)
1099
1118
 
1100
1119
  record = {
1101
1120
  'name': row.name,
@@ -1108,7 +1127,7 @@ def get_clusters_from_history(
1108
1127
  'status': status,
1109
1128
  'user_hash': user_hash,
1110
1129
  'user_name': user_name,
1111
- 'workspace': row.workspace,
1130
+ 'workspace': workspace,
1112
1131
  'last_creation_yaml': row.last_creation_yaml,
1113
1132
  'last_creation_command': row.last_creation_command,
1114
1133
  }
sky/jobs/__init__.py CHANGED
@@ -8,6 +8,8 @@ from sky.jobs.client.sdk import launch
8
8
  from sky.jobs.client.sdk import pool_apply
9
9
  from sky.jobs.client.sdk import pool_down
10
10
  from sky.jobs.client.sdk import pool_status
11
+ from sky.jobs.client.sdk import pool_sync_down_logs
12
+ from sky.jobs.client.sdk import pool_tail_logs
11
13
  from sky.jobs.client.sdk import queue
12
14
  from sky.jobs.client.sdk import tail_logs
13
15
  from sky.jobs.constants import JOBS_CLUSTER_NAME_PREFIX_LENGTH
sky/jobs/client/sdk.py CHANGED
@@ -1,7 +1,7 @@
1
1
  """SDK functions for managed jobs."""
2
2
  import json
3
3
  import typing
4
- from typing import Dict, List, Optional, Union
4
+ from typing import Any, Dict, List, Optional, Sequence, Tuple, Union
5
5
 
6
6
  import click
7
7
 
@@ -26,6 +26,7 @@ if typing.TYPE_CHECKING:
26
26
  import webbrowser
27
27
 
28
28
  import sky
29
+ from sky import backends
29
30
  from sky.serve import serve_utils
30
31
  else:
31
32
  # only used in dashboard()
@@ -45,7 +46,8 @@ def launch(
45
46
  # Internal only:
46
47
  # pylint: disable=invalid-name
47
48
  _need_confirmation: bool = False,
48
- ) -> server_common.RequestId:
49
+ ) -> server_common.RequestId[Tuple[Optional[int],
50
+ Optional['backends.ResourceHandle']]]:
49
51
  """Launches a managed job.
50
52
 
51
53
  Please refer to sky.cli.job_launch for documentation.
@@ -86,11 +88,11 @@ def launch(
86
88
  if _need_confirmation:
87
89
  job_identity = 'a managed job'
88
90
  if pool is None:
89
- request_id = sdk.optimize(dag)
90
- sdk.stream_and_get(request_id)
91
+ optimize_request_id = sdk.optimize(dag)
92
+ sdk.stream_and_get(optimize_request_id)
91
93
  else:
92
- request_id = pool_status(pool)
93
- pool_statuses = sdk.get(request_id)
94
+ pool_status_request_id = pool_status(pool)
95
+ pool_statuses = sdk.get(pool_status_request_id)
94
96
  if not pool_statuses:
95
97
  raise click.UsageError(f'Pool {pool!r} not found.')
96
98
  resources = pool_statuses[0]['requested_resources_str']
@@ -123,10 +125,12 @@ def launch(
123
125
 
124
126
  @usage_lib.entrypoint
125
127
  @server_common.check_server_healthy_or_start
126
- def queue(refresh: bool,
127
- skip_finished: bool = False,
128
- all_users: bool = False,
129
- job_ids: Optional[List[int]] = None) -> server_common.RequestId:
128
+ def queue(
129
+ refresh: bool,
130
+ skip_finished: bool = False,
131
+ all_users: bool = False,
132
+ job_ids: Optional[List[int]] = None
133
+ ) -> server_common.RequestId[List[Dict[str, Any]]]:
130
134
  """Gets statuses of managed jobs.
131
135
 
132
136
  Please refer to sky.cli.job_queue for documentation.
@@ -186,11 +190,11 @@ def queue(refresh: bool,
186
190
  @server_common.check_server_healthy_or_start
187
191
  def cancel(
188
192
  name: Optional[str] = None,
189
- job_ids: Optional[List[int]] = None,
193
+ job_ids: Optional[Sequence[int]] = None,
190
194
  all: bool = False, # pylint: disable=redefined-builtin
191
195
  all_users: bool = False,
192
196
  pool: Optional[str] = None,
193
- ) -> server_common.RequestId:
197
+ ) -> server_common.RequestId[None]:
194
198
  """Cancels managed jobs.
195
199
 
196
200
  Please refer to sky.cli.job_cancel for documentation.
@@ -278,7 +282,8 @@ def tail_logs(name: Optional[str] = None,
278
282
  json=json.loads(body.model_dump_json()),
279
283
  stream=True,
280
284
  timeout=(5, None))
281
- request_id = server_common.get_request_id(response)
285
+ request_id: server_common.RequestId[int] = server_common.get_request_id(
286
+ response)
282
287
  # Log request is idempotent when tail is 0, thus can resume previous
283
288
  # streaming point on retry.
284
289
  return sdk.stream_response(request_id=request_id,
@@ -326,12 +331,13 @@ def download_logs(
326
331
  '/jobs/download_logs',
327
332
  json=json.loads(body.model_dump_json()),
328
333
  timeout=(5, None))
329
- job_id_remote_path_dict = sdk.stream_and_get(
330
- server_common.get_request_id(response))
334
+ request_id: server_common.RequestId[Dict[
335
+ str, str]] = server_common.get_request_id(response)
336
+ job_id_remote_path_dict = sdk.stream_and_get(request_id)
331
337
  remote2local_path_dict = client_common.download_logs_from_api_server(
332
338
  job_id_remote_path_dict.values())
333
339
  return {
334
- job_id: remote2local_path_dict[remote_path]
340
+ int(job_id): remote2local_path_dict[remote_path]
335
341
  for job_id, remote_path in job_id_remote_path_dict.items()
336
342
  }
337
343
 
@@ -380,7 +386,7 @@ def pool_apply(
380
386
  # Internal only:
381
387
  # pylint: disable=invalid-name
382
388
  _need_confirmation: bool = False
383
- ) -> server_common.RequestId:
389
+ ) -> server_common.RequestId[None]:
384
390
  """Apply a config to a pool."""
385
391
  return impl.apply(task,
386
392
  pool_name,
@@ -396,7 +402,7 @@ def pool_down(
396
402
  pool_names: Optional[Union[str, List[str]]],
397
403
  all: bool = False, # pylint: disable=redefined-builtin
398
404
  purge: bool = False,
399
- ) -> server_common.RequestId:
405
+ ) -> server_common.RequestId[None]:
400
406
  """Delete a pool."""
401
407
  return impl.down(pool_names, all, purge, pool=True)
402
408
 
@@ -405,6 +411,48 @@ def pool_down(
405
411
  @server_common.check_server_healthy_or_start
406
412
  @versions.minimal_api_version(12)
407
413
  def pool_status(
408
- pool_names: Optional[Union[str, List[str]]],) -> server_common.RequestId:
414
+ pool_names: Optional[Union[str, List[str]]],
415
+ ) -> server_common.RequestId[List[Dict[str, Any]]]:
409
416
  """Query a pool."""
410
417
  return impl.status(pool_names, pool=True)
418
+
419
+
420
+ @usage_lib.entrypoint
421
+ @server_common.check_server_healthy_or_start
422
+ @rest.retry_transient_errors()
423
+ @versions.minimal_api_version(16)
424
+ def pool_tail_logs(pool_name: str,
425
+ target: Union[str, 'serve_utils.ServiceComponent'],
426
+ worker_id: Optional[int] = None,
427
+ follow: bool = True,
428
+ output_stream: Optional['io.TextIOBase'] = None,
429
+ tail: Optional[int] = None) -> None:
430
+ """Tails logs of a pool."""
431
+ return impl.tail_logs(pool_name,
432
+ target,
433
+ worker_id,
434
+ follow,
435
+ output_stream,
436
+ tail,
437
+ pool=True)
438
+
439
+
440
+ @usage_lib.entrypoint
441
+ @server_common.check_server_healthy_or_start
442
+ @rest.retry_transient_errors()
443
+ @versions.minimal_api_version(16)
444
+ def pool_sync_down_logs(pool_name: str,
445
+ local_dir: str,
446
+ *,
447
+ targets: Optional[Union[
448
+ str, 'serve_utils.ServiceComponent', Sequence[Union[
449
+ str, 'serve_utils.ServiceComponent']]]] = None,
450
+ worker_ids: Optional[List[int]] = None,
451
+ tail: Optional[int] = None) -> None:
452
+ """Sync down logs of a pool."""
453
+ return impl.sync_down_logs(pool_name,
454
+ local_dir,
455
+ targets=targets,
456
+ replica_ids=worker_ids,
457
+ tail=tail,
458
+ pool=True)
sky/jobs/controller.py CHANGED
@@ -332,7 +332,8 @@ class JobsController:
332
332
  clusters = backend_utils.get_clusters(
333
333
  cluster_names=[cluster_name],
334
334
  refresh=common.StatusRefreshMode.NONE,
335
- all_users=True)
335
+ all_users=True,
336
+ _include_is_managed=True)
336
337
  if clusters:
337
338
  assert len(clusters) == 1, (clusters, cluster_name)
338
339
  handle = clusters[0].get('handle')
sky/jobs/server/core.py CHANGED
@@ -24,6 +24,7 @@ from sky.jobs import constants as managed_job_constants
24
24
  from sky.jobs import state as managed_job_state
25
25
  from sky.jobs import utils as managed_job_utils
26
26
  from sky.provision import common as provision_common
27
+ from sky.serve import serve_state
27
28
  from sky.serve import serve_utils
28
29
  from sky.serve.server import impl
29
30
  from sky.skylet import constants as skylet_constants
@@ -108,6 +109,11 @@ def _maybe_submit_job_locally(prefix: str, dag: 'sky.Dag', pool: Optional[str],
108
109
  # Create local directory for the managed job.
109
110
  pathlib.Path(prefix).expanduser().mkdir(parents=True, exist_ok=True)
110
111
  job_ids = []
112
+ pool_hash = None
113
+ if pool is not None:
114
+ pool_hash = serve_state.get_service_hash(pool)
115
+ # Already checked in the sdk.
116
+ assert pool_hash is not None, f'Pool {pool} not found'
111
117
  for _ in range(num_jobs if num_jobs is not None else 1):
112
118
  # TODO(tian): We should have a separate name for each job when
113
119
  # submitting multiple jobs. Current blocker is that we are sharing
@@ -121,7 +127,8 @@ def _maybe_submit_job_locally(prefix: str, dag: 'sky.Dag', pool: Optional[str],
121
127
  workspace=skypilot_config.get_active_workspace(
122
128
  force_user_workspace=True),
123
129
  entrypoint=common_utils.get_current_command(),
124
- pool=pool))
130
+ pool=pool,
131
+ pool_hash=pool_hash))
125
132
  for task_id, task in enumerate(dag.tasks):
126
133
  resources_str = backend_utils.get_task_resources_str(
127
134
  task, is_managed_job=True)
@@ -843,3 +850,43 @@ def pool_status(
843
850
  List[str]]] = None,) -> List[Dict[str, Any]]:
844
851
  """Query a pool."""
845
852
  return impl.status(pool_names, pool=True)
853
+
854
+
855
+ ServiceComponentOrStr = Union[str, serve_utils.ServiceComponent]
856
+
857
+
858
+ @usage_lib.entrypoint
859
+ def pool_tail_logs(
860
+ pool_name: str,
861
+ *,
862
+ target: ServiceComponentOrStr,
863
+ worker_id: Optional[int] = None,
864
+ follow: bool = True,
865
+ tail: Optional[int] = None,
866
+ ) -> None:
867
+ """Tail logs of a pool."""
868
+ return impl.tail_logs(pool_name,
869
+ target=target,
870
+ replica_id=worker_id,
871
+ follow=follow,
872
+ tail=tail,
873
+ pool=True)
874
+
875
+
876
+ @usage_lib.entrypoint
877
+ def pool_sync_down_logs(
878
+ pool_name: str,
879
+ *,
880
+ local_dir: str,
881
+ targets: Union[ServiceComponentOrStr, List[ServiceComponentOrStr],
882
+ None] = None,
883
+ worker_ids: Optional[List[int]] = None,
884
+ tail: Optional[int] = None,
885
+ ) -> str:
886
+ """Sync down logs of a pool."""
887
+ return impl.sync_down_logs(pool_name,
888
+ local_dir=local_dir,
889
+ targets=targets,
890
+ replica_ids=worker_ids,
891
+ tail=tail,
892
+ pool=True)