skypilot-nightly 1.0.0.dev20250716__py3-none-any.whl → 1.0.0.dev20250718__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.
Files changed (65) hide show
  1. sky/__init__.py +4 -2
  2. sky/backends/backend.py +8 -4
  3. sky/backends/cloud_vm_ray_backend.py +50 -1
  4. sky/backends/docker_utils.py +1 -1
  5. sky/backends/local_docker_backend.py +2 -1
  6. sky/catalog/common.py +60 -50
  7. sky/catalog/data_fetchers/fetch_gcp.py +1 -0
  8. sky/catalog/gcp_catalog.py +24 -7
  9. sky/catalog/kubernetes_catalog.py +5 -1
  10. sky/client/cli/command.py +180 -77
  11. sky/client/cli/git.py +549 -0
  12. sky/client/common.py +1 -1
  13. sky/client/sdk.py +1 -1
  14. sky/clouds/gcp.py +1 -1
  15. sky/dashboard/out/404.html +1 -1
  16. sky/dashboard/out/_next/static/{gVXjeFhvtWXyOsx9xYNvM → FUjweqdImyeYhMYFON-Se}/_buildManifest.js +1 -1
  17. sky/dashboard/out/_next/static/chunks/1043-734e57d2b27dfe5d.js +1 -0
  18. sky/dashboard/out/_next/static/chunks/4869.bdd42f14b51d1d6f.js +16 -0
  19. sky/dashboard/out/_next/static/chunks/8969-8e0b2055bf5dd499.js +1 -0
  20. sky/dashboard/out/_next/static/chunks/{9984.b56614f3c4c5961d.js → 9984.2b5e3fa69171bff9.js} +1 -1
  21. sky/dashboard/out/_next/static/chunks/pages/clusters/[cluster]/[job]-fa406155b4223d0d.js +11 -0
  22. sky/dashboard/out/_next/static/chunks/pages/jobs/{[job]-14d404b7dd28502a.js → [job]-c5b357bfd9502fbe.js} +1 -1
  23. sky/dashboard/out/_next/static/chunks/webpack-6b0575ea521af4f3.js +1 -0
  24. sky/dashboard/out/clusters/[cluster]/[job].html +1 -1
  25. sky/dashboard/out/clusters/[cluster].html +1 -1
  26. sky/dashboard/out/clusters.html +1 -1
  27. sky/dashboard/out/config.html +1 -1
  28. sky/dashboard/out/index.html +1 -1
  29. sky/dashboard/out/infra/[context].html +1 -1
  30. sky/dashboard/out/infra.html +1 -1
  31. sky/dashboard/out/jobs/[job].html +1 -1
  32. sky/dashboard/out/jobs.html +1 -1
  33. sky/dashboard/out/users.html +1 -1
  34. sky/dashboard/out/volumes.html +1 -1
  35. sky/dashboard/out/workspace/new.html +1 -1
  36. sky/dashboard/out/workspaces/[name].html +1 -1
  37. sky/dashboard/out/workspaces.html +1 -1
  38. sky/exceptions.py +5 -0
  39. sky/execution.py +1 -1
  40. sky/jobs/client/sdk.py +1 -1
  41. sky/jobs/server/core.py +14 -0
  42. sky/provision/kubernetes/utils.py +6 -0
  43. sky/serve/client/sdk.py +1 -1
  44. sky/server/common.py +8 -3
  45. sky/server/rest.py +71 -26
  46. sky/setup_files/MANIFEST.in +1 -0
  47. sky/setup_files/dependencies.py +2 -0
  48. sky/task.py +12 -2
  49. sky/utils/command_runner.py +144 -35
  50. sky/utils/controller_utils.py +4 -3
  51. sky/utils/git.py +9 -0
  52. sky/utils/git_clone.sh +460 -0
  53. sky/utils/schemas.py +15 -1
  54. {skypilot_nightly-1.0.0.dev20250716.dist-info → skypilot_nightly-1.0.0.dev20250718.dist-info}/METADATA +3 -1
  55. {skypilot_nightly-1.0.0.dev20250716.dist-info → skypilot_nightly-1.0.0.dev20250718.dist-info}/RECORD +60 -57
  56. sky/dashboard/out/_next/static/chunks/1043-90a88c46f27b3df5.js +0 -1
  57. sky/dashboard/out/_next/static/chunks/4869.c139c0124e677fc8.js +0 -16
  58. sky/dashboard/out/_next/static/chunks/8969-743abf4bc86baf48.js +0 -1
  59. sky/dashboard/out/_next/static/chunks/pages/clusters/[cluster]/[job]-9096ea50b8e2cf9e.js +0 -6
  60. sky/dashboard/out/_next/static/chunks/webpack-3fad5d4a0541a02d.js +0 -1
  61. /sky/dashboard/out/_next/static/{gVXjeFhvtWXyOsx9xYNvM → FUjweqdImyeYhMYFON-Se}/_ssgManifest.js +0 -0
  62. {skypilot_nightly-1.0.0.dev20250716.dist-info → skypilot_nightly-1.0.0.dev20250718.dist-info}/WHEEL +0 -0
  63. {skypilot_nightly-1.0.0.dev20250716.dist-info → skypilot_nightly-1.0.0.dev20250718.dist-info}/entry_points.txt +0 -0
  64. {skypilot_nightly-1.0.0.dev20250716.dist-info → skypilot_nightly-1.0.0.dev20250718.dist-info}/licenses/LICENSE +0 -0
  65. {skypilot_nightly-1.0.0.dev20250716.dist-info → skypilot_nightly-1.0.0.dev20250718.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/219887b94512388c.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/219887b94512388c.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-3fad5d4a0541a02d.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-efc06c2733009cd3.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-c0a4f1ea606d48d2.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-771a40cde532309b.js" defer=""></script><script src="/dashboard/_next/static/chunks/616-162f3033ffcd3d31.js" defer=""></script><script src="/dashboard/_next/static/chunks/5230-df791914b54d91d9.js" defer=""></script><script src="/dashboard/_next/static/chunks/5739-5ea3ffa10fc884f2.js" defer=""></script><script src="/dashboard/_next/static/chunks/1664-d65361e92b85e786.js" defer=""></script><script src="/dashboard/_next/static/chunks/804-9f5e98ce84d46bdd.js" defer=""></script><script src="/dashboard/_next/static/chunks/1272-1ef0bf0237faccdb.js" defer=""></script><script src="/dashboard/_next/static/chunks/3947-b059261d6fa88a1f.js" defer=""></script><script src="/dashboard/_next/static/chunks/6989-eab0e9c16b64fd9f.js" defer=""></script><script src="/dashboard/_next/static/chunks/3698-9fa11dafb5cad4a6.js" defer=""></script><script src="/dashboard/_next/static/chunks/9470-b6f6a35283863a6f.js" defer=""></script><script src="/dashboard/_next/static/chunks/6990-dcb411b566e64cde.js" defer=""></script><script src="/dashboard/_next/static/chunks/8969-743abf4bc86baf48.js" defer=""></script><script src="/dashboard/_next/static/chunks/1043-90a88c46f27b3df5.js" defer=""></script><script src="/dashboard/_next/static/chunks/6601-d4a381403a8bae91.js" defer=""></script><script src="/dashboard/_next/static/chunks/938-6a9ffdaa21eee969.js" defer=""></script><script src="/dashboard/_next/static/chunks/1871-76491ac174a95278.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/clusters/%5Bcluster%5D-0c37ee1ac5f3474d.js" defer=""></script><script src="/dashboard/_next/static/gVXjeFhvtWXyOsx9xYNvM/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/gVXjeFhvtWXyOsx9xYNvM/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/clusters/[cluster]","query":{},"buildId":"gVXjeFhvtWXyOsx9xYNvM","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/219887b94512388c.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/219887b94512388c.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-6b0575ea521af4f3.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-efc06c2733009cd3.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-c0a4f1ea606d48d2.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-771a40cde532309b.js" defer=""></script><script src="/dashboard/_next/static/chunks/616-162f3033ffcd3d31.js" defer=""></script><script src="/dashboard/_next/static/chunks/5230-df791914b54d91d9.js" defer=""></script><script src="/dashboard/_next/static/chunks/5739-5ea3ffa10fc884f2.js" defer=""></script><script src="/dashboard/_next/static/chunks/1664-d65361e92b85e786.js" defer=""></script><script src="/dashboard/_next/static/chunks/804-9f5e98ce84d46bdd.js" defer=""></script><script src="/dashboard/_next/static/chunks/1272-1ef0bf0237faccdb.js" defer=""></script><script src="/dashboard/_next/static/chunks/3947-b059261d6fa88a1f.js" defer=""></script><script src="/dashboard/_next/static/chunks/6989-eab0e9c16b64fd9f.js" defer=""></script><script src="/dashboard/_next/static/chunks/3698-9fa11dafb5cad4a6.js" defer=""></script><script src="/dashboard/_next/static/chunks/9470-b6f6a35283863a6f.js" defer=""></script><script src="/dashboard/_next/static/chunks/6990-dcb411b566e64cde.js" defer=""></script><script src="/dashboard/_next/static/chunks/8969-8e0b2055bf5dd499.js" defer=""></script><script src="/dashboard/_next/static/chunks/1043-734e57d2b27dfe5d.js" defer=""></script><script src="/dashboard/_next/static/chunks/6601-d4a381403a8bae91.js" defer=""></script><script src="/dashboard/_next/static/chunks/938-6a9ffdaa21eee969.js" defer=""></script><script src="/dashboard/_next/static/chunks/1871-76491ac174a95278.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/clusters/%5Bcluster%5D-0c37ee1ac5f3474d.js" defer=""></script><script src="/dashboard/_next/static/FUjweqdImyeYhMYFON-Se/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/FUjweqdImyeYhMYFON-Se/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/clusters/[cluster]","query":{},"buildId":"FUjweqdImyeYhMYFON-Se","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/219887b94512388c.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/219887b94512388c.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-3fad5d4a0541a02d.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-efc06c2733009cd3.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-c0a4f1ea606d48d2.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-771a40cde532309b.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/clusters-102d169e87913ba1.js" defer=""></script><script src="/dashboard/_next/static/gVXjeFhvtWXyOsx9xYNvM/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/gVXjeFhvtWXyOsx9xYNvM/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/clusters","query":{},"buildId":"gVXjeFhvtWXyOsx9xYNvM","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/219887b94512388c.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/219887b94512388c.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-6b0575ea521af4f3.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-efc06c2733009cd3.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-c0a4f1ea606d48d2.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-771a40cde532309b.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/clusters-102d169e87913ba1.js" defer=""></script><script src="/dashboard/_next/static/FUjweqdImyeYhMYFON-Se/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/FUjweqdImyeYhMYFON-Se/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/clusters","query":{},"buildId":"FUjweqdImyeYhMYFON-Se","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/219887b94512388c.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/219887b94512388c.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-3fad5d4a0541a02d.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-efc06c2733009cd3.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-c0a4f1ea606d48d2.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-771a40cde532309b.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/config-a2673b256b6d416f.js" defer=""></script><script src="/dashboard/_next/static/gVXjeFhvtWXyOsx9xYNvM/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/gVXjeFhvtWXyOsx9xYNvM/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/config","query":{},"buildId":"gVXjeFhvtWXyOsx9xYNvM","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/219887b94512388c.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/219887b94512388c.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-6b0575ea521af4f3.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-efc06c2733009cd3.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-c0a4f1ea606d48d2.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-771a40cde532309b.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/config-a2673b256b6d416f.js" defer=""></script><script src="/dashboard/_next/static/FUjweqdImyeYhMYFON-Se/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/FUjweqdImyeYhMYFON-Se/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/config","query":{},"buildId":"FUjweqdImyeYhMYFON-Se","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/219887b94512388c.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/219887b94512388c.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-3fad5d4a0541a02d.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-efc06c2733009cd3.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-c0a4f1ea606d48d2.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-771a40cde532309b.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/index-927ddeebe57a8ac3.js" defer=""></script><script src="/dashboard/_next/static/gVXjeFhvtWXyOsx9xYNvM/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/gVXjeFhvtWXyOsx9xYNvM/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/","query":{},"buildId":"gVXjeFhvtWXyOsx9xYNvM","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/219887b94512388c.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/219887b94512388c.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-6b0575ea521af4f3.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-efc06c2733009cd3.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-c0a4f1ea606d48d2.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-771a40cde532309b.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/index-927ddeebe57a8ac3.js" defer=""></script><script src="/dashboard/_next/static/FUjweqdImyeYhMYFON-Se/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/FUjweqdImyeYhMYFON-Se/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/","query":{},"buildId":"FUjweqdImyeYhMYFON-Se","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/219887b94512388c.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/219887b94512388c.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-3fad5d4a0541a02d.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-efc06c2733009cd3.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-c0a4f1ea606d48d2.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-771a40cde532309b.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/infra/%5Bcontext%5D-8b0809f59034d509.js" defer=""></script><script src="/dashboard/_next/static/gVXjeFhvtWXyOsx9xYNvM/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/gVXjeFhvtWXyOsx9xYNvM/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/infra/[context]","query":{},"buildId":"gVXjeFhvtWXyOsx9xYNvM","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/219887b94512388c.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/219887b94512388c.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-6b0575ea521af4f3.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-efc06c2733009cd3.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-c0a4f1ea606d48d2.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-771a40cde532309b.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/infra/%5Bcontext%5D-8b0809f59034d509.js" defer=""></script><script src="/dashboard/_next/static/FUjweqdImyeYhMYFON-Se/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/FUjweqdImyeYhMYFON-Se/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/infra/[context]","query":{},"buildId":"FUjweqdImyeYhMYFON-Se","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/219887b94512388c.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/219887b94512388c.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-3fad5d4a0541a02d.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-efc06c2733009cd3.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-c0a4f1ea606d48d2.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-771a40cde532309b.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/infra-ae9d2f705ce582c9.js" defer=""></script><script src="/dashboard/_next/static/gVXjeFhvtWXyOsx9xYNvM/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/gVXjeFhvtWXyOsx9xYNvM/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/infra","query":{},"buildId":"gVXjeFhvtWXyOsx9xYNvM","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/219887b94512388c.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/219887b94512388c.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-6b0575ea521af4f3.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-efc06c2733009cd3.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-c0a4f1ea606d48d2.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-771a40cde532309b.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/infra-ae9d2f705ce582c9.js" defer=""></script><script src="/dashboard/_next/static/FUjweqdImyeYhMYFON-Se/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/FUjweqdImyeYhMYFON-Se/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/infra","query":{},"buildId":"FUjweqdImyeYhMYFON-Se","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/219887b94512388c.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/219887b94512388c.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-3fad5d4a0541a02d.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-efc06c2733009cd3.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-c0a4f1ea606d48d2.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-771a40cde532309b.js" defer=""></script><script src="/dashboard/_next/static/chunks/616-162f3033ffcd3d31.js" defer=""></script><script src="/dashboard/_next/static/chunks/5230-df791914b54d91d9.js" defer=""></script><script src="/dashboard/_next/static/chunks/5739-5ea3ffa10fc884f2.js" defer=""></script><script src="/dashboard/_next/static/chunks/1664-d65361e92b85e786.js" defer=""></script><script src="/dashboard/_next/static/chunks/804-9f5e98ce84d46bdd.js" defer=""></script><script src="/dashboard/_next/static/chunks/1272-1ef0bf0237faccdb.js" defer=""></script><script src="/dashboard/_next/static/chunks/6989-eab0e9c16b64fd9f.js" defer=""></script><script src="/dashboard/_next/static/chunks/3698-9fa11dafb5cad4a6.js" defer=""></script><script src="/dashboard/_next/static/chunks/9470-b6f6a35283863a6f.js" defer=""></script><script src="/dashboard/_next/static/chunks/8969-743abf4bc86baf48.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/jobs/%5Bjob%5D-14d404b7dd28502a.js" defer=""></script><script src="/dashboard/_next/static/gVXjeFhvtWXyOsx9xYNvM/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/gVXjeFhvtWXyOsx9xYNvM/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/jobs/[job]","query":{},"buildId":"gVXjeFhvtWXyOsx9xYNvM","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/219887b94512388c.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/219887b94512388c.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-6b0575ea521af4f3.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-efc06c2733009cd3.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-c0a4f1ea606d48d2.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-771a40cde532309b.js" defer=""></script><script src="/dashboard/_next/static/chunks/616-162f3033ffcd3d31.js" defer=""></script><script src="/dashboard/_next/static/chunks/5230-df791914b54d91d9.js" defer=""></script><script src="/dashboard/_next/static/chunks/5739-5ea3ffa10fc884f2.js" defer=""></script><script src="/dashboard/_next/static/chunks/1664-d65361e92b85e786.js" defer=""></script><script src="/dashboard/_next/static/chunks/804-9f5e98ce84d46bdd.js" defer=""></script><script src="/dashboard/_next/static/chunks/1272-1ef0bf0237faccdb.js" defer=""></script><script src="/dashboard/_next/static/chunks/6989-eab0e9c16b64fd9f.js" defer=""></script><script src="/dashboard/_next/static/chunks/3698-9fa11dafb5cad4a6.js" defer=""></script><script src="/dashboard/_next/static/chunks/9470-b6f6a35283863a6f.js" defer=""></script><script src="/dashboard/_next/static/chunks/8969-8e0b2055bf5dd499.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/jobs/%5Bjob%5D-c5b357bfd9502fbe.js" defer=""></script><script src="/dashboard/_next/static/FUjweqdImyeYhMYFON-Se/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/FUjweqdImyeYhMYFON-Se/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/jobs/[job]","query":{},"buildId":"FUjweqdImyeYhMYFON-Se","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/219887b94512388c.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/219887b94512388c.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-3fad5d4a0541a02d.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-efc06c2733009cd3.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-c0a4f1ea606d48d2.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-771a40cde532309b.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/jobs-5bbdc71878f0a068.js" defer=""></script><script src="/dashboard/_next/static/gVXjeFhvtWXyOsx9xYNvM/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/gVXjeFhvtWXyOsx9xYNvM/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/jobs","query":{},"buildId":"gVXjeFhvtWXyOsx9xYNvM","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/219887b94512388c.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/219887b94512388c.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-6b0575ea521af4f3.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-efc06c2733009cd3.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-c0a4f1ea606d48d2.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-771a40cde532309b.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/jobs-5bbdc71878f0a068.js" defer=""></script><script src="/dashboard/_next/static/FUjweqdImyeYhMYFON-Se/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/FUjweqdImyeYhMYFON-Se/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/jobs","query":{},"buildId":"FUjweqdImyeYhMYFON-Se","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/219887b94512388c.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/219887b94512388c.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-3fad5d4a0541a02d.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-efc06c2733009cd3.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-c0a4f1ea606d48d2.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-771a40cde532309b.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/users-19e98664bdd61643.js" defer=""></script><script src="/dashboard/_next/static/gVXjeFhvtWXyOsx9xYNvM/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/gVXjeFhvtWXyOsx9xYNvM/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/users","query":{},"buildId":"gVXjeFhvtWXyOsx9xYNvM","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/219887b94512388c.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/219887b94512388c.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-6b0575ea521af4f3.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-efc06c2733009cd3.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-c0a4f1ea606d48d2.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-771a40cde532309b.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/users-19e98664bdd61643.js" defer=""></script><script src="/dashboard/_next/static/FUjweqdImyeYhMYFON-Se/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/FUjweqdImyeYhMYFON-Se/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/users","query":{},"buildId":"FUjweqdImyeYhMYFON-Se","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/219887b94512388c.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/219887b94512388c.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-3fad5d4a0541a02d.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-efc06c2733009cd3.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-c0a4f1ea606d48d2.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-771a40cde532309b.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/volumes-61ea7ba7e56f8d06.js" defer=""></script><script src="/dashboard/_next/static/gVXjeFhvtWXyOsx9xYNvM/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/gVXjeFhvtWXyOsx9xYNvM/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/volumes","query":{},"buildId":"gVXjeFhvtWXyOsx9xYNvM","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/219887b94512388c.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/219887b94512388c.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-6b0575ea521af4f3.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-efc06c2733009cd3.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-c0a4f1ea606d48d2.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-771a40cde532309b.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/volumes-61ea7ba7e56f8d06.js" defer=""></script><script src="/dashboard/_next/static/FUjweqdImyeYhMYFON-Se/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/FUjweqdImyeYhMYFON-Se/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/volumes","query":{},"buildId":"FUjweqdImyeYhMYFON-Se","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/219887b94512388c.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/219887b94512388c.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-3fad5d4a0541a02d.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-efc06c2733009cd3.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-c0a4f1ea606d48d2.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-771a40cde532309b.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/workspace/new-5629d4e551dba1ee.js" defer=""></script><script src="/dashboard/_next/static/gVXjeFhvtWXyOsx9xYNvM/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/gVXjeFhvtWXyOsx9xYNvM/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/workspace/new","query":{},"buildId":"gVXjeFhvtWXyOsx9xYNvM","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/219887b94512388c.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/219887b94512388c.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-6b0575ea521af4f3.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-efc06c2733009cd3.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-c0a4f1ea606d48d2.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-771a40cde532309b.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/workspace/new-5629d4e551dba1ee.js" defer=""></script><script src="/dashboard/_next/static/FUjweqdImyeYhMYFON-Se/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/FUjweqdImyeYhMYFON-Se/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/workspace/new","query":{},"buildId":"FUjweqdImyeYhMYFON-Se","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/219887b94512388c.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/219887b94512388c.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-3fad5d4a0541a02d.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-efc06c2733009cd3.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-c0a4f1ea606d48d2.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-771a40cde532309b.js" defer=""></script><script src="/dashboard/_next/static/chunks/616-162f3033ffcd3d31.js" defer=""></script><script src="/dashboard/_next/static/chunks/5230-df791914b54d91d9.js" defer=""></script><script src="/dashboard/_next/static/chunks/5739-5ea3ffa10fc884f2.js" defer=""></script><script src="/dashboard/_next/static/chunks/1664-d65361e92b85e786.js" defer=""></script><script src="/dashboard/_next/static/chunks/804-9f5e98ce84d46bdd.js" defer=""></script><script src="/dashboard/_next/static/chunks/1272-1ef0bf0237faccdb.js" defer=""></script><script src="/dashboard/_next/static/chunks/3947-b059261d6fa88a1f.js" defer=""></script><script src="/dashboard/_next/static/chunks/6989-eab0e9c16b64fd9f.js" defer=""></script><script src="/dashboard/_next/static/chunks/3698-9fa11dafb5cad4a6.js" defer=""></script><script src="/dashboard/_next/static/chunks/9470-b6f6a35283863a6f.js" defer=""></script><script src="/dashboard/_next/static/chunks/6990-dcb411b566e64cde.js" defer=""></script><script src="/dashboard/_next/static/chunks/8969-743abf4bc86baf48.js" defer=""></script><script src="/dashboard/_next/static/chunks/1043-90a88c46f27b3df5.js" defer=""></script><script src="/dashboard/_next/static/chunks/6601-d4a381403a8bae91.js" defer=""></script><script src="/dashboard/_next/static/chunks/938-6a9ffdaa21eee969.js" defer=""></script><script src="/dashboard/_next/static/chunks/1141-d8c6404a7c6fffe6.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/workspaces/%5Bname%5D-7c0187f43757a548.js" defer=""></script><script src="/dashboard/_next/static/gVXjeFhvtWXyOsx9xYNvM/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/gVXjeFhvtWXyOsx9xYNvM/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/workspaces/[name]","query":{},"buildId":"gVXjeFhvtWXyOsx9xYNvM","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/219887b94512388c.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/219887b94512388c.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-6b0575ea521af4f3.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-efc06c2733009cd3.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-c0a4f1ea606d48d2.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-771a40cde532309b.js" defer=""></script><script src="/dashboard/_next/static/chunks/616-162f3033ffcd3d31.js" defer=""></script><script src="/dashboard/_next/static/chunks/5230-df791914b54d91d9.js" defer=""></script><script src="/dashboard/_next/static/chunks/5739-5ea3ffa10fc884f2.js" defer=""></script><script src="/dashboard/_next/static/chunks/1664-d65361e92b85e786.js" defer=""></script><script src="/dashboard/_next/static/chunks/804-9f5e98ce84d46bdd.js" defer=""></script><script src="/dashboard/_next/static/chunks/1272-1ef0bf0237faccdb.js" defer=""></script><script src="/dashboard/_next/static/chunks/3947-b059261d6fa88a1f.js" defer=""></script><script src="/dashboard/_next/static/chunks/6989-eab0e9c16b64fd9f.js" defer=""></script><script src="/dashboard/_next/static/chunks/3698-9fa11dafb5cad4a6.js" defer=""></script><script src="/dashboard/_next/static/chunks/9470-b6f6a35283863a6f.js" defer=""></script><script src="/dashboard/_next/static/chunks/6990-dcb411b566e64cde.js" defer=""></script><script src="/dashboard/_next/static/chunks/8969-8e0b2055bf5dd499.js" defer=""></script><script src="/dashboard/_next/static/chunks/1043-734e57d2b27dfe5d.js" defer=""></script><script src="/dashboard/_next/static/chunks/6601-d4a381403a8bae91.js" defer=""></script><script src="/dashboard/_next/static/chunks/938-6a9ffdaa21eee969.js" defer=""></script><script src="/dashboard/_next/static/chunks/1141-d8c6404a7c6fffe6.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/workspaces/%5Bname%5D-7c0187f43757a548.js" defer=""></script><script src="/dashboard/_next/static/FUjweqdImyeYhMYFON-Se/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/FUjweqdImyeYhMYFON-Se/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/workspaces/[name]","query":{},"buildId":"FUjweqdImyeYhMYFON-Se","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/219887b94512388c.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/219887b94512388c.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-3fad5d4a0541a02d.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-efc06c2733009cd3.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-c0a4f1ea606d48d2.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-771a40cde532309b.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/workspaces-a1e43d9ef51a9cea.js" defer=""></script><script src="/dashboard/_next/static/gVXjeFhvtWXyOsx9xYNvM/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/gVXjeFhvtWXyOsx9xYNvM/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/workspaces","query":{},"buildId":"gVXjeFhvtWXyOsx9xYNvM","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/219887b94512388c.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/219887b94512388c.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-6b0575ea521af4f3.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-efc06c2733009cd3.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-c0a4f1ea606d48d2.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-771a40cde532309b.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/workspaces-a1e43d9ef51a9cea.js" defer=""></script><script src="/dashboard/_next/static/FUjweqdImyeYhMYFON-Se/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/FUjweqdImyeYhMYFON-Se/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/workspaces","query":{},"buildId":"FUjweqdImyeYhMYFON-Se","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
sky/exceptions.py CHANGED
@@ -637,3 +637,8 @@ class ServerTemporarilyUnavailableError(Exception):
637
637
  class RestfulPolicyError(Exception):
638
638
  """Raised when failed to call a RESTful policy."""
639
639
  pass
640
+
641
+
642
+ class GitError(Exception):
643
+ """Raised when a git operation fails."""
644
+ pass
sky/execution.py CHANGED
@@ -431,7 +431,7 @@ def _execute_dag(
431
431
  logger.info(ux_utils.starting_message('Syncing files.'))
432
432
 
433
433
  if do_workdir:
434
- backend.sync_workdir(handle, task.workdir)
434
+ backend.sync_workdir(handle, task.workdir, task.envs_and_secrets)
435
435
 
436
436
  if do_file_mounts:
437
437
  backend.sync_file_mounts(handle, task.file_mounts,
sky/jobs/client/sdk.py CHANGED
@@ -192,7 +192,7 @@ def cancel(
192
192
 
193
193
  @usage_lib.entrypoint
194
194
  @server_common.check_server_healthy_or_start
195
- @rest.retry_on_server_unavailable()
195
+ @rest.retry_transient_errors()
196
196
  def tail_logs(name: Optional[str] = None,
197
197
  job_id: Optional[int] = None,
198
198
  follow: bool = True,
sky/jobs/server/core.py CHANGED
@@ -147,6 +147,18 @@ def launch(
147
147
  None if dryrun.
148
148
  """
149
149
  entrypoint = task
150
+ # using hasattr instead of isinstance to avoid importing sky
151
+ if hasattr(task, 'metadata'):
152
+ metadata = task.metadata
153
+ else:
154
+ # we are a Dag, not a Task
155
+ if len(task.tasks) == 1:
156
+ metadata = task.tasks[0].metadata
157
+ else:
158
+ # doesn't make sense to have a git commit since there might be
159
+ # different metadatas for each task
160
+ metadata = {}
161
+
150
162
  dag_uuid = str(uuid.uuid4().hex[:4])
151
163
  dag = dag_utils.convert_entrypoint_to_dag(entrypoint)
152
164
  dag.resolve_and_validate_volumes()
@@ -311,6 +323,8 @@ def launch(
311
323
  controller_task.set_resources(controller_resources)
312
324
 
313
325
  controller_task.managed_job_dag = dag
326
+ # pylint: disable=protected-access
327
+ controller_task._metadata = metadata
314
328
 
315
329
  logger.info(
316
330
  f'{colorama.Fore.YELLOW}'
@@ -554,6 +554,9 @@ class GKELabelFormatter(GPULabelFormatter):
554
554
  return acc
555
555
  elif is_tpu_on_gke(value):
556
556
  return value
557
+ elif value == '':
558
+ # heterogenous cluster may have empty labels for cpu nodes.
559
+ return ''
557
560
  else:
558
561
  raise ValueError(
559
562
  f'Invalid accelerator name in GKE cluster: {value}')
@@ -993,6 +996,9 @@ class GKEAutoscaler(Autoscaler):
993
996
  node_accelerator_type = (
994
997
  GKELabelFormatter.get_accelerator_from_label_value(
995
998
  accelerator['acceleratorType']))
999
+ # handle heterogenous nodes.
1000
+ if not node_accelerator_type:
1001
+ continue
996
1002
  node_accelerator_count = accelerator['acceleratorCount']
997
1003
  if node_accelerator_type == requested_gpu_type and int(
998
1004
  node_accelerator_count) >= requested_gpu_count:
sky/serve/client/sdk.py CHANGED
@@ -292,7 +292,7 @@ def status(
292
292
 
293
293
  @usage_lib.entrypoint
294
294
  @server_common.check_server_healthy_or_start
295
- @rest.retry_on_server_unavailable()
295
+ @rest.retry_transient_errors()
296
296
  def tail_logs(service_name: str,
297
297
  target: Union[str, 'serve_utils.ServiceComponent'],
298
298
  replica_id: Optional[int] = None,
sky/server/common.py CHANGED
@@ -371,6 +371,10 @@ def get_api_server_status(endpoint: Optional[str] = None) -> ApiServerInfo:
371
371
 
372
372
 
373
373
  def handle_request_error(response: 'requests.Response') -> None:
374
+ # Keep the original HTTPError if the response code >= 400
375
+ response.raise_for_status()
376
+ # Other status codes are not expected neither, e.g. we do not expect to
377
+ # handle redirection here.
374
378
  if response.status_code != 200:
375
379
  with ux_utils.print_exception_no_traceback():
376
380
  raise RuntimeError(
@@ -706,9 +710,10 @@ def process_mounts_in_task_on_api_server(task: str, env_vars: Dict[str, str],
706
710
  continue
707
711
  if 'workdir' in task_config:
708
712
  workdir = task_config['workdir']
709
- task_config['workdir'] = str(
710
- client_file_mounts_dir /
711
- file_mounts_mapping[workdir].lstrip('/'))
713
+ if isinstance(workdir, str):
714
+ task_config['workdir'] = str(
715
+ client_file_mounts_dir /
716
+ file_mounts_mapping[workdir].lstrip('/'))
712
717
  if workdir_only:
713
718
  continue
714
719
  if 'file_mounts' in task_config:
sky/server/rest.py CHANGED
@@ -42,12 +42,79 @@ class RetryContext:
42
42
  self.line_processed = 0
43
43
 
44
44
 
45
- def retry_on_server_unavailable(max_wait_seconds: int = 600,
46
- initial_backoff: float = 5.0,
47
- max_backoff_factor: int = 5):
45
+ @contextlib.contextmanager
46
+ def _retry_in_context():
47
+ token = _RETRY_CONTEXT.set(RetryContext())
48
+ try:
49
+ yield
50
+ finally:
51
+ _RETRY_CONTEXT.reset(token)
52
+
53
+
54
+ def get_retry_context() -> Optional[RetryContext]:
55
+ return _RETRY_CONTEXT.get()
56
+
57
+
58
+ def retry_transient_errors(max_retries: int = 3,
59
+ initial_backoff=1,
60
+ max_backoff_factor=5):
61
+ """Decorator that retries a function when a transient error is caught.
62
+
63
+ This decorator is mainly used to decorate idempotent SDK functions to make
64
+ it more robust to transient errors.
65
+
66
+ Args:
67
+ max_retries: Maximum number of retries
68
+ initial_backoff: Initial backoff time in seconds
69
+ max_backoff_factor: Maximum backoff factor for exponential backoff
70
+ """
71
+
72
+ def is_transient_error(e: Exception) -> bool:
73
+ if isinstance(e, requests.exceptions.HTTPError):
74
+ # Only server error is considered as transient.
75
+ return e.response.status_code >= 500
76
+ # It is hard to enumerate all other errors that are transient, e.g.
77
+ # broken pipe, connection refused, etc. Instead, it is safer to assume
78
+ # all other errors might be transient since we only retry for 3 times
79
+ # by default. For permanent errors that we do not know now, we can
80
+ # exclude them here in the future.
81
+ return True
82
+
83
+ def decorator(func: F) -> F:
84
+
85
+ @functools.wraps(func)
86
+ def wrapper(*args, **kwargs):
87
+ backoff = common_utils.Backoff(initial_backoff, max_backoff_factor)
88
+ with _retry_in_context():
89
+ for retry_cnt in range(max_retries):
90
+ try:
91
+ return func(*args, **kwargs)
92
+ except Exception as e: # pylint: disable=broad-except
93
+ if retry_cnt >= max_retries - 1:
94
+ # Retries exhausted.
95
+ raise
96
+ if not is_transient_error(e):
97
+ # Permanent error, no need to retry.
98
+ raise
99
+ logger.debug(f'Retry {func.__name__} due to {e}, '
100
+ f'attempt {retry_cnt + 1}/{max_retries}')
101
+ time.sleep(backoff.current_backoff())
102
+
103
+ return cast(F, wrapper)
104
+
105
+ return decorator
106
+
107
+
108
+ def _retry_on_server_unavailable(max_wait_seconds: int = 600,
109
+ initial_backoff: float = 5.0,
110
+ max_backoff_factor: int = 5):
48
111
  """Decorator that retries a function when ServerTemporarilyUnavailableError
49
112
  is caught.
50
113
 
114
+ This decorator is mainly used to decorate a Restful API call to make
115
+ the API call wait for server recovery when server is temporarily
116
+ unavailable.
117
+
51
118
  Args:
52
119
  max_wait_seconds: Maximum number of seconds to wait for the server to
53
120
  be healthy
@@ -55,15 +122,6 @@ def retry_on_server_unavailable(max_wait_seconds: int = 600,
55
122
  max_backoff_factor: Maximum backoff factor for exponential backoff
56
123
 
57
124
  Notes(dev):
58
- This decorator is mainly used in two scenarios:
59
- 1. Decorate a Restful API call to make the API call wait for server
60
- recovery when server is temporarily unavailable. APIs like /api/get
61
- and /api/stream should not be retried since sending them to a new
62
- replica of API server will not work.
63
- 2. Decorate a SDK function to make the entire SDK function call get
64
- retried when /api/get or /logs raises a retryable error. This
65
- is typically triggered by a graceful upgrade of the API server,
66
- where the pending requests and logs requests will be interrupted.
67
125
  """
68
126
 
69
127
  def decorator(func: F) -> F:
@@ -111,19 +169,6 @@ def retry_on_server_unavailable(max_wait_seconds: int = 600,
111
169
  return decorator
112
170
 
113
171
 
114
- @contextlib.contextmanager
115
- def _retry_in_context():
116
- token = _RETRY_CONTEXT.set(RetryContext())
117
- try:
118
- yield
119
- finally:
120
- _RETRY_CONTEXT.reset(token)
121
-
122
-
123
- def get_retry_context() -> Optional[RetryContext]:
124
- return _RETRY_CONTEXT.get()
125
-
126
-
127
172
  def handle_server_unavailable(response: 'requests.Response') -> None:
128
173
  if response.status_code == 503:
129
174
  # TODO(aylei): Hacky, depends on how nginx controller handles backends
@@ -135,7 +180,7 @@ def handle_server_unavailable(response: 'requests.Response') -> None:
135
180
  'Please try again later.')
136
181
 
137
182
 
138
- @retry_on_server_unavailable()
183
+ @_retry_on_server_unavailable()
139
184
  def request(method, url, **kwargs) -> 'requests.Response':
140
185
  """Send a request to the API server, retry on server temporarily
141
186
  unavailable."""
@@ -17,3 +17,4 @@ include sky/utils/kubernetes/*
17
17
  include sky/server/html/*
18
18
  recursive-include sky/dashboard/out *
19
19
  include sky/users/*.conf
20
+ include sky/utils/*.sh
@@ -66,6 +66,8 @@ install_requires = [
66
66
  'prometheus_client>=0.8.0',
67
67
  'passlib',
68
68
  'pyjwt',
69
+ 'gitpython',
70
+ 'types-paramiko',
69
71
  ]
70
72
 
71
73
  server_dependencies = [
sky/task.py CHANGED
@@ -245,7 +245,7 @@ class Task:
245
245
  run: Optional[CommandOrCommandGen] = None,
246
246
  envs: Optional[Dict[str, str]] = None,
247
247
  secrets: Optional[Dict[str, str]] = None,
248
- workdir: Optional[str] = None,
248
+ workdir: Optional[Union[str, Dict[str, Any]]] = None,
249
249
  num_nodes: Optional[int] = None,
250
250
  volumes: Optional[Dict[str, str]] = None,
251
251
  # Advanced:
@@ -301,10 +301,14 @@ class Task:
301
301
  secrets: A dictionary of secret environment variables to set before
302
302
  running the setup and run commands. These will be redacted in logs
303
303
  and YAML output.
304
- workdir: The local working directory. This directory will be synced
304
+ workdir: The local working directory or a git repository.
305
+ For a local working directory, this directory will be synced
305
306
  to a location on the remote VM(s), and ``setup`` and ``run``
306
307
  commands will be run under that location (thus, they can rely on
307
308
  relative paths when invoking binaries).
309
+ If a git repository is provided, the repository will be cloned to
310
+ the working directory and the ``setup`` and ``run`` commands will
311
+ be run under the cloned repository.
308
312
  num_nodes: The number of nodes to provision for this Task. If None,
309
313
  treated as 1 node. If > 1, each node will execute its own
310
314
  setup/run command, where ``run`` can either be a str, meaning all
@@ -498,6 +502,12 @@ class Task:
498
502
  """
499
503
  if self.workdir is None:
500
504
  return
505
+ # Only expand the workdir if it is a string
506
+ if isinstance(self.workdir, dict):
507
+ git_ref = self.workdir.get('ref')
508
+ if git_ref is not None:
509
+ self._metadata['git_commit'] = git_ref
510
+ return
501
511
  user_workdir = self.workdir
502
512
  self.workdir = os.path.abspath(os.path.expanduser(user_workdir))
503
513
  if not os.path.isdir(self.workdir):