skypilot-nightly 1.0.0.dev20250819__py3-none-any.whl → 1.0.0.dev20250821__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 (80) hide show
  1. sky/__init__.py +5 -3
  2. sky/backends/cloud_vm_ray_backend.py +15 -14
  3. sky/backends/wheel_utils.py +2 -1
  4. sky/client/cli/command.py +20 -16
  5. sky/client/cli/flags.py +3 -3
  6. sky/core.py +1 -1
  7. sky/dashboard/out/404.html +1 -1
  8. sky/dashboard/out/_next/static/chunks/3015-6c9c09593b1e67b6.js +1 -0
  9. sky/dashboard/out/_next/static/chunks/{3785.bc5d2853355c9c47.js → 3785.d5b86f6ebc88e6e6.js} +1 -1
  10. sky/dashboard/out/_next/static/chunks/{9277.71481d5b2e606e33.js → 4783.c485f48348349f47.js} +8 -3
  11. sky/dashboard/out/_next/static/chunks/{6633-efe924b9b8136699.js → 7205-88191679e7988c57.js} +9 -4
  12. sky/dashboard/out/_next/static/chunks/8969-4a6f1a928fb6d370.js +1 -0
  13. sky/dashboard/out/_next/static/chunks/{8838.e7953f42af2b0544.js → 9946.3b7b43c217ff70ec.js} +9 -4
  14. sky/dashboard/out/_next/static/chunks/pages/clusters/{[cluster]-ec747e4f2dc39b57.js → [cluster]-a0527109c2fab467.js} +7 -2
  15. sky/dashboard/out/_next/static/chunks/pages/jobs/[job]-dd64309c3fe67ed2.js +11 -0
  16. sky/dashboard/out/_next/static/chunks/pages/{jobs-4b3ba1792dc6f21d.js → jobs-7421e63ac35f8fce.js} +1 -1
  17. sky/dashboard/out/_next/static/chunks/pages/workspaces/{[name]-65f72dee417237ef.js → [name]-de06e613e20bc977.js} +1 -1
  18. sky/dashboard/out/_next/static/chunks/pages/{workspaces-338de9df523d883a.js → workspaces-be35b22e2046564c.js} +1 -1
  19. sky/dashboard/out/_next/static/chunks/webpack-6e76f636a048e145.js +1 -0
  20. sky/dashboard/out/_next/static/{tYn7R2be3cQPYJfTxxE09 → wN25tc2rkvOkO-qkzIhcD}/_buildManifest.js +1 -1
  21. sky/dashboard/out/clusters/[cluster]/[job].html +1 -1
  22. sky/dashboard/out/clusters/[cluster].html +1 -1
  23. sky/dashboard/out/clusters.html +1 -1
  24. sky/dashboard/out/config.html +1 -1
  25. sky/dashboard/out/index.html +1 -1
  26. sky/dashboard/out/infra/[context].html +1 -1
  27. sky/dashboard/out/infra.html +1 -1
  28. sky/dashboard/out/jobs/[job].html +1 -1
  29. sky/dashboard/out/jobs/pools/[pool].html +1 -1
  30. sky/dashboard/out/jobs.html +1 -1
  31. sky/dashboard/out/users.html +1 -1
  32. sky/dashboard/out/volumes.html +1 -1
  33. sky/dashboard/out/workspace/new.html +1 -1
  34. sky/dashboard/out/workspaces/[name].html +1 -1
  35. sky/dashboard/out/workspaces.html +1 -1
  36. sky/exceptions.py +6 -1
  37. sky/global_user_state.py +18 -11
  38. sky/jobs/server/core.py +1 -1
  39. sky/models.py +1 -0
  40. sky/provision/aws/config.py +11 -11
  41. sky/provision/aws/instance.py +30 -27
  42. sky/provision/do/utils.py +2 -2
  43. sky/provision/docker_utils.py +20 -1
  44. sky/provision/kubernetes/network_utils.py +3 -3
  45. sky/provision/kubernetes/utils.py +2 -2
  46. sky/provision/kubernetes/volume.py +2 -0
  47. sky/resources.py +17 -7
  48. sky/serve/replica_managers.py +7 -0
  49. sky/serve/server/impl.py +1 -1
  50. sky/server/requests/payloads.py +1 -0
  51. sky/server/requests/serializers/encoders.py +14 -2
  52. sky/server/server.py +33 -0
  53. sky/setup_files/dependencies.py +17 -11
  54. sky/skypilot_config.py +4 -4
  55. sky/users/permission.py +2 -1
  56. sky/utils/common.py +27 -7
  57. sky/utils/common_utils.py +13 -9
  58. sky/utils/directory_utils.py +12 -0
  59. sky/utils/env_options.py +3 -0
  60. sky/utils/kubernetes/gpu_labeler.py +3 -3
  61. sky/utils/schemas.py +1 -0
  62. sky/utils/serialize_utils.py +16 -0
  63. sky/volumes/client/sdk.py +10 -7
  64. sky/volumes/server/core.py +12 -3
  65. sky/volumes/volume.py +17 -3
  66. {skypilot_nightly-1.0.0.dev20250819.dist-info → skypilot_nightly-1.0.0.dev20250821.dist-info}/METADATA +21 -13
  67. {skypilot_nightly-1.0.0.dev20250819.dist-info → skypilot_nightly-1.0.0.dev20250821.dist-info}/RECORD +76 -74
  68. sky/dashboard/out/_next/static/chunks/3015-bf218e4973bf5c8f.js +0 -1
  69. sky/dashboard/out/_next/static/chunks/8969-23c8fbdb8b397d59.js +0 -1
  70. sky/dashboard/out/_next/static/chunks/pages/jobs/[job]-ad2cd5aab787bc15.js +0 -6
  71. sky/dashboard/out/_next/static/chunks/webpack-008593a02784a2df.js +0 -1
  72. /sky/dashboard/out/_next/static/chunks/{1121-2edb8ab2ba080a76.js → 1121-8afcf719ea87debc.js} +0 -0
  73. /sky/dashboard/out/_next/static/chunks/{1141-2f60a90b7d76838e.js → 1141-943efc7aff0f0c06.js} +0 -0
  74. /sky/dashboard/out/_next/static/chunks/{6856-e6f350f567182e87.js → 6856-049014c6d43d127b.js} +0 -0
  75. /sky/dashboard/out/_next/static/chunks/pages/jobs/pools/{[pool]-7d4182df6625fe10.js → [pool]-07349868f7905d37.js} +0 -0
  76. /sky/dashboard/out/_next/static/{tYn7R2be3cQPYJfTxxE09 → wN25tc2rkvOkO-qkzIhcD}/_ssgManifest.js +0 -0
  77. {skypilot_nightly-1.0.0.dev20250819.dist-info → skypilot_nightly-1.0.0.dev20250821.dist-info}/WHEEL +0 -0
  78. {skypilot_nightly-1.0.0.dev20250819.dist-info → skypilot_nightly-1.0.0.dev20250821.dist-info}/entry_points.txt +0 -0
  79. {skypilot_nightly-1.0.0.dev20250819.dist-info → skypilot_nightly-1.0.0.dev20250821.dist-info}/licenses/LICENSE +0 -0
  80. {skypilot_nightly-1.0.0.dev20250819.dist-info → skypilot_nightly-1.0.0.dev20250821.dist-info}/top_level.txt +0 -0
@@ -1 +1 @@
1
- <!DOCTYPE html><html><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><meta name="next-head-count" content="2"/><link rel="preload" href="/dashboard/_next/static/css/4614e06482d7309e.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/4614e06482d7309e.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/dashboard/_next/static/chunks/polyfills-78c92fac7aa8fdd8.js"></script><script src="/dashboard/_next/static/chunks/webpack-008593a02784a2df.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-cf60a09ccd051a10.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-f15ccb73239a3bf1.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-ce361c6959bc2001.js" defer=""></script><script src="/dashboard/_next/static/chunks/616-3d59f75e2ccf9321.js" defer=""></script><script src="/dashboard/_next/static/chunks/6130-2be46d70a38f1e82.js" defer=""></script><script src="/dashboard/_next/static/chunks/5739-d67458fcb1386c92.js" defer=""></script><script src="/dashboard/_next/static/chunks/7411-b15471acd2cba716.js" defer=""></script><script src="/dashboard/_next/static/chunks/1272-1ef0bf0237faccdb.js" defer=""></script><script src="/dashboard/_next/static/chunks/754-d0da8ab45f9509e9.js" defer=""></script><script src="/dashboard/_next/static/chunks/6989-01359c57e018caa4.js" defer=""></script><script src="/dashboard/_next/static/chunks/3850-ff4a9a69d978632b.js" defer=""></script><script src="/dashboard/_next/static/chunks/8969-23c8fbdb8b397d59.js" defer=""></script><script src="/dashboard/_next/static/chunks/6135-4b4d5e824b7f9d3c.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/jobs/%5Bjob%5D-ad2cd5aab787bc15.js" defer=""></script><script src="/dashboard/_next/static/tYn7R2be3cQPYJfTxxE09/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/tYn7R2be3cQPYJfTxxE09/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/jobs/[job]","query":{},"buildId":"tYn7R2be3cQPYJfTxxE09","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-6e76f636a048e145.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-cf60a09ccd051a10.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-f15ccb73239a3bf1.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-ce361c6959bc2001.js" defer=""></script><script src="/dashboard/_next/static/chunks/616-3d59f75e2ccf9321.js" defer=""></script><script src="/dashboard/_next/static/chunks/6130-2be46d70a38f1e82.js" defer=""></script><script src="/dashboard/_next/static/chunks/5739-d67458fcb1386c92.js" defer=""></script><script src="/dashboard/_next/static/chunks/7411-b15471acd2cba716.js" defer=""></script><script src="/dashboard/_next/static/chunks/1272-1ef0bf0237faccdb.js" defer=""></script><script src="/dashboard/_next/static/chunks/754-d0da8ab45f9509e9.js" defer=""></script><script src="/dashboard/_next/static/chunks/6989-01359c57e018caa4.js" defer=""></script><script src="/dashboard/_next/static/chunks/3850-ff4a9a69d978632b.js" defer=""></script><script src="/dashboard/_next/static/chunks/8969-4a6f1a928fb6d370.js" defer=""></script><script src="/dashboard/_next/static/chunks/6135-4b4d5e824b7f9d3c.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/jobs/%5Bjob%5D-dd64309c3fe67ed2.js" defer=""></script><script src="/dashboard/_next/static/wN25tc2rkvOkO-qkzIhcD/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/wN25tc2rkvOkO-qkzIhcD/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/jobs/[job]","query":{},"buildId":"wN25tc2rkvOkO-qkzIhcD","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
@@ -1 +1 @@
1
- <!DOCTYPE html><html><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><meta name="next-head-count" content="2"/><link rel="preload" href="/dashboard/_next/static/css/4614e06482d7309e.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/4614e06482d7309e.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/dashboard/_next/static/chunks/polyfills-78c92fac7aa8fdd8.js"></script><script src="/dashboard/_next/static/chunks/webpack-008593a02784a2df.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-cf60a09ccd051a10.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-f15ccb73239a3bf1.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-ce361c6959bc2001.js" defer=""></script><script src="/dashboard/_next/static/chunks/616-3d59f75e2ccf9321.js" defer=""></script><script src="/dashboard/_next/static/chunks/6130-2be46d70a38f1e82.js" defer=""></script><script src="/dashboard/_next/static/chunks/5739-d67458fcb1386c92.js" defer=""></script><script src="/dashboard/_next/static/chunks/1272-1ef0bf0237faccdb.js" defer=""></script><script src="/dashboard/_next/static/chunks/754-d0da8ab45f9509e9.js" defer=""></script><script src="/dashboard/_next/static/chunks/6989-01359c57e018caa4.js" defer=""></script><script src="/dashboard/_next/static/chunks/3850-ff4a9a69d978632b.js" defer=""></script><script src="/dashboard/_next/static/chunks/8969-23c8fbdb8b397d59.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/jobs/pools/%5Bpool%5D-7d4182df6625fe10.js" defer=""></script><script src="/dashboard/_next/static/tYn7R2be3cQPYJfTxxE09/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/tYn7R2be3cQPYJfTxxE09/_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":"tYn7R2be3cQPYJfTxxE09","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-6e76f636a048e145.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-cf60a09ccd051a10.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-f15ccb73239a3bf1.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-ce361c6959bc2001.js" defer=""></script><script src="/dashboard/_next/static/chunks/616-3d59f75e2ccf9321.js" defer=""></script><script src="/dashboard/_next/static/chunks/6130-2be46d70a38f1e82.js" defer=""></script><script src="/dashboard/_next/static/chunks/5739-d67458fcb1386c92.js" defer=""></script><script src="/dashboard/_next/static/chunks/1272-1ef0bf0237faccdb.js" defer=""></script><script src="/dashboard/_next/static/chunks/754-d0da8ab45f9509e9.js" defer=""></script><script src="/dashboard/_next/static/chunks/6989-01359c57e018caa4.js" defer=""></script><script src="/dashboard/_next/static/chunks/3850-ff4a9a69d978632b.js" defer=""></script><script src="/dashboard/_next/static/chunks/8969-4a6f1a928fb6d370.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/jobs/pools/%5Bpool%5D-07349868f7905d37.js" defer=""></script><script src="/dashboard/_next/static/wN25tc2rkvOkO-qkzIhcD/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/wN25tc2rkvOkO-qkzIhcD/_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":"wN25tc2rkvOkO-qkzIhcD","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
@@ -1 +1 @@
1
- <!DOCTYPE html><html><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><meta name="next-head-count" content="2"/><link rel="preload" href="/dashboard/_next/static/css/4614e06482d7309e.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/4614e06482d7309e.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/dashboard/_next/static/chunks/polyfills-78c92fac7aa8fdd8.js"></script><script src="/dashboard/_next/static/chunks/webpack-008593a02784a2df.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-cf60a09ccd051a10.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-f15ccb73239a3bf1.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-ce361c6959bc2001.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/jobs-4b3ba1792dc6f21d.js" defer=""></script><script src="/dashboard/_next/static/tYn7R2be3cQPYJfTxxE09/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/tYn7R2be3cQPYJfTxxE09/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/jobs","query":{},"buildId":"tYn7R2be3cQPYJfTxxE09","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-6e76f636a048e145.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-cf60a09ccd051a10.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-f15ccb73239a3bf1.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-ce361c6959bc2001.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/jobs-7421e63ac35f8fce.js" defer=""></script><script src="/dashboard/_next/static/wN25tc2rkvOkO-qkzIhcD/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/wN25tc2rkvOkO-qkzIhcD/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/jobs","query":{},"buildId":"wN25tc2rkvOkO-qkzIhcD","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
@@ -1 +1 @@
1
- <!DOCTYPE html><html><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><meta name="next-head-count" content="2"/><link rel="preload" href="/dashboard/_next/static/css/4614e06482d7309e.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/4614e06482d7309e.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/dashboard/_next/static/chunks/polyfills-78c92fac7aa8fdd8.js"></script><script src="/dashboard/_next/static/chunks/webpack-008593a02784a2df.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-cf60a09ccd051a10.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-f15ccb73239a3bf1.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-ce361c6959bc2001.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/users-018bf31cda52e11b.js" defer=""></script><script src="/dashboard/_next/static/tYn7R2be3cQPYJfTxxE09/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/tYn7R2be3cQPYJfTxxE09/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/users","query":{},"buildId":"tYn7R2be3cQPYJfTxxE09","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-6e76f636a048e145.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-cf60a09ccd051a10.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-f15ccb73239a3bf1.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-ce361c6959bc2001.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/users-018bf31cda52e11b.js" defer=""></script><script src="/dashboard/_next/static/wN25tc2rkvOkO-qkzIhcD/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/wN25tc2rkvOkO-qkzIhcD/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/users","query":{},"buildId":"wN25tc2rkvOkO-qkzIhcD","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
@@ -1 +1 @@
1
- <!DOCTYPE html><html><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><meta name="next-head-count" content="2"/><link rel="preload" href="/dashboard/_next/static/css/4614e06482d7309e.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/4614e06482d7309e.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/dashboard/_next/static/chunks/polyfills-78c92fac7aa8fdd8.js"></script><script src="/dashboard/_next/static/chunks/webpack-008593a02784a2df.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-cf60a09ccd051a10.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-f15ccb73239a3bf1.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-ce361c6959bc2001.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/volumes-739726d6b823f532.js" defer=""></script><script src="/dashboard/_next/static/tYn7R2be3cQPYJfTxxE09/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/tYn7R2be3cQPYJfTxxE09/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/volumes","query":{},"buildId":"tYn7R2be3cQPYJfTxxE09","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-6e76f636a048e145.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-cf60a09ccd051a10.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-f15ccb73239a3bf1.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-ce361c6959bc2001.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/volumes-739726d6b823f532.js" defer=""></script><script src="/dashboard/_next/static/wN25tc2rkvOkO-qkzIhcD/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/wN25tc2rkvOkO-qkzIhcD/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/volumes","query":{},"buildId":"wN25tc2rkvOkO-qkzIhcD","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
@@ -1 +1 @@
1
- <!DOCTYPE html><html><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><meta name="next-head-count" content="2"/><link rel="preload" href="/dashboard/_next/static/css/4614e06482d7309e.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/4614e06482d7309e.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/dashboard/_next/static/chunks/polyfills-78c92fac7aa8fdd8.js"></script><script src="/dashboard/_next/static/chunks/webpack-008593a02784a2df.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-cf60a09ccd051a10.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-f15ccb73239a3bf1.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-ce361c6959bc2001.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/workspace/new-3f88a1c7e86a3f86.js" defer=""></script><script src="/dashboard/_next/static/tYn7R2be3cQPYJfTxxE09/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/tYn7R2be3cQPYJfTxxE09/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/workspace/new","query":{},"buildId":"tYn7R2be3cQPYJfTxxE09","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-6e76f636a048e145.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-cf60a09ccd051a10.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-f15ccb73239a3bf1.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-ce361c6959bc2001.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/workspace/new-3f88a1c7e86a3f86.js" defer=""></script><script src="/dashboard/_next/static/wN25tc2rkvOkO-qkzIhcD/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/wN25tc2rkvOkO-qkzIhcD/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/workspace/new","query":{},"buildId":"wN25tc2rkvOkO-qkzIhcD","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
@@ -1 +1 @@
1
- <!DOCTYPE html><html><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><meta name="next-head-count" content="2"/><link rel="preload" href="/dashboard/_next/static/css/4614e06482d7309e.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/4614e06482d7309e.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/dashboard/_next/static/chunks/polyfills-78c92fac7aa8fdd8.js"></script><script src="/dashboard/_next/static/chunks/webpack-008593a02784a2df.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-cf60a09ccd051a10.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-f15ccb73239a3bf1.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-ce361c6959bc2001.js" defer=""></script><script src="/dashboard/_next/static/chunks/616-3d59f75e2ccf9321.js" defer=""></script><script src="/dashboard/_next/static/chunks/6130-2be46d70a38f1e82.js" defer=""></script><script src="/dashboard/_next/static/chunks/5739-d67458fcb1386c92.js" defer=""></script><script src="/dashboard/_next/static/chunks/7411-b15471acd2cba716.js" defer=""></script><script src="/dashboard/_next/static/chunks/1272-1ef0bf0237faccdb.js" defer=""></script><script src="/dashboard/_next/static/chunks/6633-efe924b9b8136699.js" defer=""></script><script src="/dashboard/_next/static/chunks/6989-01359c57e018caa4.js" defer=""></script><script src="/dashboard/_next/static/chunks/3850-ff4a9a69d978632b.js" defer=""></script><script src="/dashboard/_next/static/chunks/8969-23c8fbdb8b397d59.js" defer=""></script><script src="/dashboard/_next/static/chunks/6990-08b2a1cae076a943.js" defer=""></script><script src="/dashboard/_next/static/chunks/6135-4b4d5e824b7f9d3c.js" defer=""></script><script src="/dashboard/_next/static/chunks/1121-2edb8ab2ba080a76.js" defer=""></script><script src="/dashboard/_next/static/chunks/6601-06114c982db410b6.js" defer=""></script><script src="/dashboard/_next/static/chunks/3015-bf218e4973bf5c8f.js" defer=""></script><script src="/dashboard/_next/static/chunks/1141-2f60a90b7d76838e.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/workspaces/%5Bname%5D-65f72dee417237ef.js" defer=""></script><script src="/dashboard/_next/static/tYn7R2be3cQPYJfTxxE09/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/tYn7R2be3cQPYJfTxxE09/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/workspaces/[name]","query":{},"buildId":"tYn7R2be3cQPYJfTxxE09","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-6e76f636a048e145.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-cf60a09ccd051a10.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-f15ccb73239a3bf1.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-ce361c6959bc2001.js" defer=""></script><script src="/dashboard/_next/static/chunks/616-3d59f75e2ccf9321.js" defer=""></script><script src="/dashboard/_next/static/chunks/6130-2be46d70a38f1e82.js" defer=""></script><script src="/dashboard/_next/static/chunks/5739-d67458fcb1386c92.js" defer=""></script><script src="/dashboard/_next/static/chunks/7411-b15471acd2cba716.js" defer=""></script><script src="/dashboard/_next/static/chunks/1272-1ef0bf0237faccdb.js" defer=""></script><script src="/dashboard/_next/static/chunks/7205-88191679e7988c57.js" defer=""></script><script src="/dashboard/_next/static/chunks/6989-01359c57e018caa4.js" defer=""></script><script src="/dashboard/_next/static/chunks/3850-ff4a9a69d978632b.js" defer=""></script><script src="/dashboard/_next/static/chunks/8969-4a6f1a928fb6d370.js" defer=""></script><script src="/dashboard/_next/static/chunks/6990-08b2a1cae076a943.js" defer=""></script><script src="/dashboard/_next/static/chunks/6135-4b4d5e824b7f9d3c.js" defer=""></script><script src="/dashboard/_next/static/chunks/1121-8afcf719ea87debc.js" defer=""></script><script src="/dashboard/_next/static/chunks/6601-06114c982db410b6.js" defer=""></script><script src="/dashboard/_next/static/chunks/3015-6c9c09593b1e67b6.js" defer=""></script><script src="/dashboard/_next/static/chunks/1141-943efc7aff0f0c06.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/workspaces/%5Bname%5D-de06e613e20bc977.js" defer=""></script><script src="/dashboard/_next/static/wN25tc2rkvOkO-qkzIhcD/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/wN25tc2rkvOkO-qkzIhcD/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/workspaces/[name]","query":{},"buildId":"wN25tc2rkvOkO-qkzIhcD","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
@@ -1 +1 @@
1
- <!DOCTYPE html><html><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><meta name="next-head-count" content="2"/><link rel="preload" href="/dashboard/_next/static/css/4614e06482d7309e.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/4614e06482d7309e.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/dashboard/_next/static/chunks/polyfills-78c92fac7aa8fdd8.js"></script><script src="/dashboard/_next/static/chunks/webpack-008593a02784a2df.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-cf60a09ccd051a10.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-f15ccb73239a3bf1.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-ce361c6959bc2001.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/workspaces-338de9df523d883a.js" defer=""></script><script src="/dashboard/_next/static/tYn7R2be3cQPYJfTxxE09/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/tYn7R2be3cQPYJfTxxE09/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/workspaces","query":{},"buildId":"tYn7R2be3cQPYJfTxxE09","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-6e76f636a048e145.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-cf60a09ccd051a10.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-f15ccb73239a3bf1.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-ce361c6959bc2001.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/workspaces-be35b22e2046564c.js" defer=""></script><script src="/dashboard/_next/static/wN25tc2rkvOkO-qkzIhcD/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/wN25tc2rkvOkO-qkzIhcD/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/workspaces","query":{},"buildId":"wN25tc2rkvOkO-qkzIhcD","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
sky/exceptions.py CHANGED
@@ -6,11 +6,12 @@ import types
6
6
  import typing
7
7
  from typing import Any, Dict, List, Optional, Sequence
8
8
 
9
+ from sky.backends import backend
9
10
  from sky.utils import env_options
11
+ from sky.utils import serialize_utils
10
12
 
11
13
  if typing.TYPE_CHECKING:
12
14
  from sky import jobs as managed_jobs
13
- from sky.backends import backend
14
15
  from sky.skylet import job_lib
15
16
  from sky.utils import status_lib
16
17
 
@@ -92,6 +93,10 @@ def serialize_exception(e: BaseException) -> Dict[str, Any]:
92
93
  attr_v = attributes[attr_k]
93
94
  if isinstance(attr_v, types.TracebackType):
94
95
  attributes[attr_k] = traceback.format_tb(attr_v)
96
+ if isinstance(attr_v, backend.ResourceHandle):
97
+ attributes[attr_k] = (
98
+ serialize_utils.prepare_handle_for_backwards_compatibility(
99
+ attr_v))
95
100
 
96
101
  data = {
97
102
  'type': e.__class__.__name__,
sky/global_user_state.py CHANGED
@@ -55,6 +55,13 @@ _SQLALCHEMY_ENGINE_LOCK = threading.Lock()
55
55
  DEFAULT_CLUSTER_EVENT_RETENTION_HOURS = 24.0
56
56
  MIN_CLUSTER_EVENT_DAEMON_INTERVAL_SECONDS = 3600
57
57
 
58
+ _UNIQUE_CONSTRAINT_FAILED_ERROR_MSGS = [
59
+ # sqlite
60
+ 'UNIQUE constraint failed',
61
+ # postgres
62
+ 'duplicate key value violates unique constraint',
63
+ ]
64
+
58
65
  Base = declarative.declarative_base()
59
66
 
60
67
  config_table = sqlalchemy.Table(
@@ -735,17 +742,17 @@ def add_cluster_event(cluster_name: str,
735
742
  ))
736
743
  session.commit()
737
744
  except sqlalchemy.exc.IntegrityError as e:
738
- if 'UNIQUE constraint failed' in str(e):
739
- # This can happen if the cluster event is added twice.
740
- # We can ignore this error unless the caller requests
741
- # to expose the error.
742
- if expose_duplicate_error:
743
- raise db_utils.UniqueConstraintViolationError(
744
- value=reason, message=str(e))
745
- else:
746
- pass
747
- else:
748
- raise e
745
+ for msg in _UNIQUE_CONSTRAINT_FAILED_ERROR_MSGS:
746
+ if msg in str(e):
747
+ # This can happen if the cluster event is added twice.
748
+ # We can ignore this error unless the caller requests
749
+ # to expose the error.
750
+ if expose_duplicate_error:
751
+ raise db_utils.UniqueConstraintViolationError(
752
+ value=reason, message=str(e))
753
+ else:
754
+ return
755
+ raise e
749
756
 
750
757
 
751
758
  def get_last_cluster_event(cluster_hash: str,
sky/jobs/server/core.py CHANGED
@@ -188,11 +188,11 @@ def launch(
188
188
 
189
189
  dag_uuid = str(uuid.uuid4().hex[:4])
190
190
  dag = dag_utils.convert_entrypoint_to_dag(entrypoint)
191
- dag.resolve_and_validate_volumes()
192
191
  # Always apply the policy again here, even though it might have been applied
193
192
  # in the CLI. This is to ensure that we apply the policy to the final DAG
194
193
  # and get the mutated config.
195
194
  dag, mutated_user_config = admin_policy_utils.apply(dag)
195
+ dag.resolve_and_validate_volumes()
196
196
  if not dag.is_chain():
197
197
  with ux_utils.print_exception_no_traceback():
198
198
  raise ValueError('Only single-task or chain DAG is '
sky/models.py CHANGED
@@ -108,3 +108,4 @@ class VolumeConfig(pydantic.BaseModel):
108
108
  name_on_cloud: str
109
109
  size: Optional[str]
110
110
  config: Dict[str, Any] = {}
111
+ labels: Optional[Dict[str, str]] = None
@@ -498,8 +498,8 @@ def _vpc_id_from_security_group_ids(ec2: 'mypy_boto3_ec2.ServiceResource',
498
498
  return vpc_ids[0]
499
499
 
500
500
 
501
- def _get_vpc_id_by_name(ec2: 'mypy_boto3_ec2.ServiceResource', vpc_name: str,
502
- region: str) -> str:
501
+ def get_vpc_id_by_name(ec2: 'mypy_boto3_ec2.ServiceResource', vpc_name: str,
502
+ region: str) -> str:
503
503
  """Returns the VPC ID of the unique VPC with a given name.
504
504
 
505
505
  Exits with code 1 if:
@@ -532,7 +532,7 @@ def _get_subnet_and_vpc_id(ec2: 'mypy_boto3_ec2.ServiceResource',
532
532
  use_internal_ips: bool,
533
533
  vpc_name: Optional[str]) -> Tuple[Any, str]:
534
534
  if vpc_name is not None:
535
- vpc_id_of_sg = _get_vpc_id_by_name(ec2, vpc_name, region)
535
+ vpc_id_of_sg = get_vpc_id_by_name(ec2, vpc_name, region)
536
536
  elif security_group_ids:
537
537
  vpc_id_of_sg = _vpc_id_from_security_group_ids(ec2, security_group_ids)
538
538
  else:
@@ -614,8 +614,8 @@ def _get_or_create_vpc_security_group(ec2: 'mypy_boto3_ec2.ServiceResource',
614
614
  due to AWS service issues.
615
615
  """
616
616
  # Figure out which security groups with this name exist for each VPC...
617
- security_group = _get_security_group_from_vpc_id(ec2, vpc_id,
618
- expected_sg_name)
617
+ security_group = get_security_group_from_vpc_id(ec2, vpc_id,
618
+ expected_sg_name)
619
619
  if security_group is not None:
620
620
  return security_group
621
621
 
@@ -631,7 +631,7 @@ def _get_or_create_vpc_security_group(ec2: 'mypy_boto3_ec2.ServiceResource',
631
631
  # The security group already exists, but we didn't see it
632
632
  # because of eventual consistency.
633
633
  logger.warning(f'{expected_sg_name} already exists when creating.')
634
- security_group = _get_security_group_from_vpc_id(
634
+ security_group = get_security_group_from_vpc_id(
635
635
  ec2, vpc_id, expected_sg_name)
636
636
  assert (security_group is not None and
637
637
  security_group.group_name == expected_sg_name), (
@@ -646,8 +646,8 @@ def _get_or_create_vpc_security_group(ec2: 'mypy_boto3_ec2.ServiceResource',
646
646
  logger.warning(message)
647
647
  raise exceptions.NoClusterLaunchedError(message) from e
648
648
 
649
- security_group = _get_security_group_from_vpc_id(ec2, vpc_id,
650
- expected_sg_name)
649
+ security_group = get_security_group_from_vpc_id(ec2, vpc_id,
650
+ expected_sg_name)
651
651
  assert security_group is not None, 'Failed to create security group'
652
652
  logger.info(f'Created new security group {colorama.Style.BRIGHT}'
653
653
  f'{security_group.group_name}{colorama.Style.RESET_ALL} '
@@ -655,9 +655,9 @@ def _get_or_create_vpc_security_group(ec2: 'mypy_boto3_ec2.ServiceResource',
655
655
  return security_group
656
656
 
657
657
 
658
- def _get_security_group_from_vpc_id(ec2: 'mypy_boto3_ec2.ServiceResource',
659
- vpc_id: str,
660
- group_name: str) -> Optional[Any]:
658
+ def get_security_group_from_vpc_id(ec2: 'mypy_boto3_ec2.ServiceResource',
659
+ vpc_id: str,
660
+ group_name: str) -> Optional[Any]:
661
661
  """Get security group by VPC ID and group name."""
662
662
  existing_groups = list(
663
663
  ec2.security_groups.filter(Filters=[{
@@ -18,6 +18,7 @@ from sky.clouds import aws as aws_cloud
18
18
  from sky.clouds.utils import aws_utils
19
19
  from sky.provision import common
20
20
  from sky.provision import constants
21
+ from sky.provision.aws import config as aws_config
21
22
  from sky.provision.aws import utils
22
23
  from sky.utils import common_utils
23
24
  from sky.utils import resources_utils
@@ -685,7 +686,9 @@ def terminate_instances(
685
686
  filters,
686
687
  included_instances=None,
687
688
  excluded_instances=None)
688
- default_sg = _get_sg_from_name(ec2, aws_cloud.DEFAULT_SECURITY_GROUP_NAME)
689
+ default_sg = aws_config.get_security_group_from_vpc_id(
690
+ ec2, _get_vpc_id(provider_config),
691
+ aws_cloud.DEFAULT_SECURITY_GROUP_NAME)
689
692
  if sg_name == aws_cloud.DEFAULT_SECURITY_GROUP_NAME:
690
693
  # Case 1: The default SG is used, we don't need to ensure instance are
691
694
  # terminated.
@@ -727,30 +730,6 @@ def terminate_instances(
727
730
  # of most cloud implementations (including AWS).
728
731
 
729
732
 
730
- def _get_sg_from_name(
731
- ec2: Any,
732
- sg_name: str,
733
- ) -> Any:
734
- # GroupNames will only filter SGs in the default VPC, so we need to use
735
- # Filters here. Ref:
736
- # https://boto3.amazonaws.com/v1/documentation/api/1.26.112/reference/services/ec2/service-resource/security_groups.html # pylint: disable=line-too-long
737
- sgs = ec2.security_groups.filter(Filters=[{
738
- 'Name': 'group-name',
739
- 'Values': [sg_name]
740
- }])
741
- num_sg = len(list(sgs))
742
- if num_sg == 0:
743
- logger.warning(f'Expected security group {sg_name} not found. ')
744
- return None
745
- if num_sg > 1:
746
- # TODO(tian): Better handle this case. Maybe we can check when creating
747
- # the SG and throw an error if there is already an existing SG with the
748
- # same name.
749
- logger.warning(f'Found {num_sg} security groups with name {sg_name}. ')
750
- return None
751
- return list(sgs)[0]
752
-
753
-
754
733
  def _maybe_move_to_new_sg(
755
734
  instance: Any,
756
735
  expected_sg: Any,
@@ -803,7 +782,9 @@ def open_ports(
803
782
  with ux_utils.print_exception_no_traceback():
804
783
  raise ValueError('Instance with cluster name '
805
784
  f'{cluster_name_on_cloud} not found.')
806
- sg = _get_sg_from_name(ec2, sg_name)
785
+ sg = aws_config.get_security_group_from_vpc_id(ec2,
786
+ _get_vpc_id(provider_config),
787
+ sg_name)
807
788
  if sg is None:
808
789
  with ux_utils.print_exception_no_traceback():
809
790
  raise ValueError('Cannot find new security group '
@@ -899,7 +880,9 @@ def cleanup_ports(
899
880
  # We only want to delete the SG that is dedicated to this cluster (i.e.,
900
881
  # this cluster have opened some ports).
901
882
  return
902
- sg = _get_sg_from_name(ec2, sg_name)
883
+ sg = aws_config.get_security_group_from_vpc_id(ec2,
884
+ _get_vpc_id(provider_config),
885
+ sg_name)
903
886
  if sg is None:
904
887
  logger.warning(
905
888
  'Find security group failed. Skip cleanup security group.')
@@ -1010,3 +993,23 @@ def get_cluster_info(
1010
993
  provider_name='aws',
1011
994
  provider_config=provider_config,
1012
995
  )
996
+
997
+
998
+ def _get_vpc_id(provider_config: Dict[str, Any]) -> str:
999
+ region = provider_config['region']
1000
+ ec2 = _default_ec2_resource(provider_config['region'])
1001
+ if 'vpc_name' in provider_config:
1002
+ return aws_config.get_vpc_id_by_name(ec2, provider_config['vpc_name'],
1003
+ region)
1004
+ else:
1005
+ # Retrieve the default VPC name from the region.
1006
+ response = ec2.meta.client.describe_vpcs(Filters=[{
1007
+ 'Name': 'isDefault',
1008
+ 'Values': ['true']
1009
+ }])
1010
+ if len(response['Vpcs']) == 0:
1011
+ raise ValueError(f'No default VPC found in region {region}')
1012
+ elif len(response['Vpcs']) > 1:
1013
+ raise ValueError(f'Multiple default VPCs found in region {region}')
1014
+ else:
1015
+ return response['Vpcs'][0]['VpcId']
sky/provision/do/utils.py CHANGED
@@ -30,7 +30,7 @@ POSSIBLE_CREDENTIALS_PATHS = [
30
30
  INITIAL_BACKOFF_SECONDS = 10
31
31
  MAX_BACKOFF_FACTOR = 10
32
32
  MAX_ATTEMPTS = 6
33
- SSH_KEY_NAME_ON_DO = f'sky-key-{common_utils.get_user_hash()}'
33
+ SSH_KEY_NAME_ON_DO_PREFIX = 'sky-key-'
34
34
 
35
35
  _client = None
36
36
  _ssh_key_id = None
@@ -125,7 +125,7 @@ def ssh_key_id(public_key: str):
125
125
 
126
126
  request = {
127
127
  'public_key': public_key,
128
- 'name': SSH_KEY_NAME_ON_DO,
128
+ 'name': SSH_KEY_NAME_ON_DO_PREFIX + common_utils.get_user_hash(),
129
129
  }
130
130
  _ssh_key_id = client().ssh_keys.create(body=request)['ssh_key']
131
131
  return _ssh_key_id
@@ -83,6 +83,21 @@ def check_docker_image(cname, docker_cmd):
83
83
  return _check_helper(cname, '.Config.Image', docker_cmd)
84
84
 
85
85
 
86
+ def maybe_remove_container_cmds(container_name, docker_cmd):
87
+ """Remove the container if it exists. If not, it will be a no-op.
88
+ """
89
+ docker_rm = [
90
+ docker_cmd,
91
+ 'rm',
92
+ '-f',
93
+ container_name,
94
+ '2>/dev/null',
95
+ '||',
96
+ 'true',
97
+ ]
98
+ return ' '.join(docker_rm)
99
+
100
+
86
101
  def docker_start_cmds(
87
102
  image,
88
103
  container_name,
@@ -285,6 +300,10 @@ class DockerInitializer:
285
300
  'sudo mv /tmp/daemon.json /etc/docker/daemon.json;'
286
301
  'sudo systemctl restart docker; } || true')
287
302
  user_docker_run_options = self.docker_config.get('run_options', [])
303
+ remove_container_cmd = maybe_remove_container_cmds(
304
+ self.container_name,
305
+ self.docker_cmd,
306
+ )
288
307
  start_command = docker_start_cmds(
289
308
  specific_image,
290
309
  self.container_name,
@@ -292,7 +311,7 @@ class DockerInitializer:
292
311
  self._auto_configure_shm(user_docker_run_options)),
293
312
  self.docker_cmd,
294
313
  )
295
- self._run(start_command)
314
+ self._run(f'{remove_container_cmd}; {start_command}')
296
315
 
297
316
  # SkyPilot: Setup Commands.
298
317
  # TODO(zhwu): the following setups should be aligned with the kubernetes
@@ -4,13 +4,13 @@ import time
4
4
  import typing
5
5
  from typing import Dict, List, Optional, Tuple, Union
6
6
 
7
- import sky
8
7
  from sky import exceptions
9
8
  from sky import sky_logging
10
9
  from sky import skypilot_config
11
10
  from sky.adaptors import common as adaptors_common
12
11
  from sky.adaptors import kubernetes
13
12
  from sky.provision.kubernetes import utils as kubernetes_utils
13
+ from sky.utils import directory_utils
14
14
  from sky.utils import kubernetes_enums
15
15
  from sky.utils import ux_utils
16
16
 
@@ -80,7 +80,7 @@ def get_networking_mode(
80
80
  def fill_loadbalancer_template(namespace: str, context: Optional[str],
81
81
  service_name: str, ports: List[int],
82
82
  selector_key: str, selector_value: str) -> Dict:
83
- template_path = os.path.join(sky.__root_dir__, 'templates',
83
+ template_path = os.path.join(directory_utils.get_sky_dir(), 'templates',
84
84
  _LOADBALANCER_TEMPLATE_NAME)
85
85
  if not os.path.exists(template_path):
86
86
  raise FileNotFoundError(
@@ -116,7 +116,7 @@ def fill_ingress_template(namespace: str, context: Optional[str],
116
116
  service_details: List[Tuple[str, int,
117
117
  str]], ingress_name: str,
118
118
  selector_key: str, selector_value: str) -> Dict:
119
- template_path = os.path.join(sky.__root_dir__, 'templates',
119
+ template_path = os.path.join(directory_utils.get_sky_dir(), 'templates',
120
120
  _INGRESS_TEMPLATE_NAME)
121
121
  if not os.path.exists(template_path):
122
122
  raise FileNotFoundError(
@@ -14,7 +14,6 @@ import typing
14
14
  from typing import Any, Callable, Dict, List, Optional, Set, Tuple, Union
15
15
  from urllib.parse import urlparse
16
16
 
17
- import sky
18
17
  from sky import clouds
19
18
  from sky import exceptions
20
19
  from sky import global_user_state
@@ -31,6 +30,7 @@ from sky.skylet import constants
31
30
  from sky.utils import annotations
32
31
  from sky.utils import common_utils
33
32
  from sky.utils import config_utils
33
+ from sky.utils import directory_utils
34
34
  from sky.utils import env_options
35
35
  from sky.utils import kubernetes_enums
36
36
  from sky.utils import schemas
@@ -2444,7 +2444,7 @@ def clean_zombie_ssh_jump_pod(namespace: str, context: Optional[str],
2444
2444
 
2445
2445
  def fill_ssh_jump_template(ssh_key_secret: str, ssh_jump_image: str,
2446
2446
  ssh_jump_name: str, service_type: str) -> Dict:
2447
- template_path = os.path.join(sky.__root_dir__, 'templates',
2447
+ template_path = os.path.join(directory_utils.get_sky_dir(), 'templates',
2448
2448
  'kubernetes-ssh-jump.yml.j2')
2449
2449
  if not os.path.exists(template_path):
2450
2450
  raise FileNotFoundError(
@@ -203,6 +203,8 @@ def _get_pvc_spec(namespace: str,
203
203
  },
204
204
  }
205
205
  }
206
+ if config.labels:
207
+ pvc_spec['metadata']['labels'].update(config.labels)
206
208
  storage_class = config.config.get('storage_class_name')
207
209
  if storage_class is not None:
208
210
  pvc_spec['spec']['storageClassName'] = storage_class
sky/resources.py CHANGED
@@ -1260,10 +1260,14 @@ class Resources:
1260
1260
  def extract_docker_image(self) -> Optional[str]:
1261
1261
  if self.image_id is None:
1262
1262
  return None
1263
- if len(self.image_id) == 1 and self.region in self.image_id:
1264
- image_id = self.image_id[self.region]
1265
- if image_id.startswith('docker:'):
1266
- return image_id[len('docker:'):]
1263
+ # Handle dict image_id
1264
+ if len(self.image_id) == 1:
1265
+ # Check if the single key matches the region or is None (any region)
1266
+ image_key = list(self.image_id.keys())[0]
1267
+ if image_key == self.region or image_key is None:
1268
+ image_id = self.image_id[image_key]
1269
+ if image_id.startswith('docker:'):
1270
+ return image_id[len('docker:'):]
1267
1271
  return None
1268
1272
 
1269
1273
  def _try_validate_image_id(self) -> None:
@@ -1333,13 +1337,19 @@ class Resources:
1333
1337
  'Kubernetes, please explicitly specify the cloud.') from e
1334
1338
 
1335
1339
  if self._region is not None:
1336
- if self._region not in self._image_id:
1340
+ # If the image_id has None as key (region-agnostic),
1341
+ # use it for any region
1342
+ if None in self._image_id:
1343
+ # Replace None key with the actual region
1344
+ self._image_id = {self._region: self._image_id[None]}
1345
+ elif self._region not in self._image_id:
1337
1346
  with ux_utils.print_exception_no_traceback():
1338
1347
  raise ValueError(
1339
1348
  f'image_id {self._image_id} should contain the image '
1340
1349
  f'for the specified region {self._region}.')
1341
- # Narrow down the image_id to the specified region.
1342
- self._image_id = {self._region: self._image_id[self._region]}
1350
+ else:
1351
+ # Narrow down the image_id to the specified region.
1352
+ self._image_id = {self._region: self._image_id[self._region]}
1343
1353
 
1344
1354
  # Check the image_id's are valid.
1345
1355
  for region, image_id in self._image_id.items():
@@ -48,6 +48,13 @@ _PROCESS_POOL_REFRESH_INTERVAL = 20
48
48
  _RETRY_INIT_GAP_SECONDS = 60
49
49
  _DEFAULT_DRAIN_SECONDS = 120
50
50
 
51
+ # TODO(tian): Backward compatibility. Remove this after 3 minor release, i.e.
52
+ # 0.13.0. We move the ProcessStatus to common_utils.ProcessStatus in #6666, but
53
+ # old ReplicaInfo in database will still tries to unpickle using ProcessStatus
54
+ # in replica_managers. We set this alias to avoid breaking changes. See #6729
55
+ # for more details.
56
+ ProcessStatus = common_utils.ProcessStatus
57
+
51
58
 
52
59
  # TODO(tian): Combine this with
53
60
  # sky/spot/recovery_strategy.py::StrategyExecutor::launch
sky/serve/server/impl.py CHANGED
@@ -129,11 +129,11 @@ def up(
129
129
  f'{constants.CLUSTER_NAME_VALID_REGEX}')
130
130
 
131
131
  dag = dag_utils.convert_entrypoint_to_dag(task)
132
- dag.resolve_and_validate_volumes()
133
132
  # Always apply the policy again here, even though it might have been applied
134
133
  # in the CLI. This is to ensure that we apply the policy to the final DAG
135
134
  # and get the mutated config.
136
135
  dag, mutated_user_config = admin_policy_utils.apply(dag)
136
+ dag.resolve_and_validate_volumes()
137
137
  dag.pre_mount_volumes()
138
138
  task = dag.tasks[0]
139
139
  assert task.service is not None
@@ -453,6 +453,7 @@ class VolumeApplyBody(RequestBody):
453
453
  zone: Optional[str] = None
454
454
  size: Optional[str] = None
455
455
  config: Optional[Dict[str, Any]] = None
456
+ labels: Optional[Dict[str, str]] = None
456
457
 
457
458
 
458
459
  class VolumeDeleteBody(RequestBody):