skypilot-nightly 1.0.0.dev20250526__py3-none-any.whl → 1.0.0.dev20250528__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.
- sky/__init__.py +2 -2
- sky/adaptors/kubernetes.py +13 -1
- sky/backends/cloud_vm_ray_backend.py +2 -2
- sky/check.py +32 -6
- sky/cli.py +5 -22
- sky/client/cli.py +5 -22
- sky/client/sdk.py +5 -2
- sky/clouds/cloud.py +2 -2
- sky/clouds/kubernetes.py +12 -7
- sky/clouds/service_catalog/kubernetes_catalog.py +4 -0
- sky/clouds/ssh.py +24 -8
- sky/core.py +20 -2
- sky/dashboard/out/404.html +1 -1
- sky/dashboard/out/_next/static/Mx1iAbDQn1jMHh3UHmK3R/_buildManifest.js +1 -0
- sky/dashboard/out/_next/static/chunks/121-8f55ee3fa6301784.js +20 -0
- sky/dashboard/out/_next/static/chunks/{573-f17bd89d9f9118b3.js → 173-7db8607cefc20f70.js} +5 -5
- sky/dashboard/out/_next/static/chunks/236-d6900c828331f664.js +6 -0
- sky/dashboard/out/_next/static/chunks/293-351268365226d251.js +1 -0
- sky/dashboard/out/_next/static/chunks/{498-d7722313e5e5b4e6.js → 320-afea3ddcc5bd1c6c.js} +1 -16
- sky/dashboard/out/_next/static/chunks/470-4d003c441839094d.js +1 -0
- sky/dashboard/out/_next/static/chunks/578-9146658cead92981.js +6 -0
- sky/dashboard/out/_next/static/chunks/843-256ec920f6d5f41f.js +11 -0
- sky/dashboard/out/_next/static/chunks/856-62b87c68917b08ed.js +1 -0
- sky/dashboard/out/_next/static/chunks/973-1a09cac61cfcc1e1.js +1 -0
- sky/dashboard/out/_next/static/chunks/pages/clusters/[cluster]/[job]-159bffb2fa34ed54.js +6 -0
- sky/dashboard/out/_next/static/chunks/pages/clusters/[cluster]-9506c00257d10dbd.js +1 -0
- sky/dashboard/out/_next/static/chunks/pages/{clusters-9e6d1ec6e1ac5b29.js → clusters-943992b84fd6f4ee.js} +1 -1
- sky/dashboard/out/_next/static/chunks/pages/config-41738d1896fc02fe.js +6 -0
- sky/dashboard/out/_next/static/chunks/pages/infra-881fcd902fbbd0e5.js +6 -0
- sky/dashboard/out/_next/static/chunks/pages/jobs/[job]-2c29e97a6aa50dd4.js +6 -0
- sky/dashboard/out/_next/static/chunks/pages/jobs-a4efc09e61988f8d.js +1 -0
- sky/dashboard/out/_next/static/chunks/pages/users-b2634885d67c49a6.js +6 -0
- sky/dashboard/out/_next/static/chunks/pages/workspace/{new-bbf436f41381e169.js → new-579b3203c7c19d84.js} +1 -1
- sky/dashboard/out/_next/static/chunks/pages/workspaces/{[name]-7733c960685b4385.js → [name]-9388e38fac73ee8f.js} +1 -1
- sky/dashboard/out/_next/static/chunks/pages/workspaces-610c49ae3619ee85.js +1 -0
- sky/dashboard/out/_next/static/css/ffd1cd601648c303.css +3 -0
- sky/dashboard/out/clusters/[cluster]/[job].html +1 -1
- sky/dashboard/out/clusters/[cluster].html +1 -1
- sky/dashboard/out/clusters.html +1 -1
- sky/dashboard/out/config.html +1 -0
- sky/dashboard/out/index.html +1 -1
- sky/dashboard/out/infra.html +1 -1
- sky/dashboard/out/jobs/[job].html +1 -1
- sky/dashboard/out/jobs.html +1 -1
- sky/dashboard/out/users.html +1 -1
- sky/dashboard/out/workspace/new.html +1 -1
- sky/dashboard/out/workspaces/[name].html +1 -1
- sky/dashboard/out/workspaces.html +1 -1
- sky/global_user_state.py +181 -134
- sky/provision/kubernetes/utils.py +4 -4
- sky/server/constants.py +1 -1
- sky/server/requests/payloads.py +18 -5
- sky/server/requests/serializers/decoders.py +0 -11
- sky/server/server.py +25 -14
- sky/setup_files/dependencies.py +1 -0
- sky/skylet/constants.py +4 -0
- sky/skypilot_config.py +4 -0
- sky/utils/db_utils.py +34 -46
- sky/utils/kubernetes/exec_kubeconfig_converter.py +19 -0
- sky/utils/schemas.py +57 -5
- sky/utils/subprocess_utils.py +2 -3
- sky/workspaces/core.py +186 -50
- sky/workspaces/server.py +25 -0
- {skypilot_nightly-1.0.0.dev20250526.dist-info → skypilot_nightly-1.0.0.dev20250528.dist-info}/METADATA +2 -1
- {skypilot_nightly-1.0.0.dev20250526.dist-info → skypilot_nightly-1.0.0.dev20250528.dist-info}/RECORD +71 -67
- {skypilot_nightly-1.0.0.dev20250526.dist-info → skypilot_nightly-1.0.0.dev20250528.dist-info}/WHEEL +1 -1
- sky/dashboard/out/_next/static/7GEgRyZKRaSnYZCV1Jwol/_buildManifest.js +0 -1
- sky/dashboard/out/_next/static/chunks/25-062253ea41fb8eec.js +0 -6
- sky/dashboard/out/_next/static/chunks/480-5a0de8b6570ea105.js +0 -1
- sky/dashboard/out/_next/static/chunks/488-50d843fdb5396d32.js +0 -15
- sky/dashboard/out/_next/static/chunks/578-d351125af46c293f.js +0 -6
- sky/dashboard/out/_next/static/chunks/734-a6e01d7f98904741.js +0 -1
- sky/dashboard/out/_next/static/chunks/938-59956af3950b02ed.js +0 -1
- sky/dashboard/out/_next/static/chunks/pages/clusters/[cluster]/[job]-3b5aad09a25f64b7.js +0 -1
- sky/dashboard/out/_next/static/chunks/pages/clusters/[cluster]-9529d9e882a0e75c.js +0 -16
- sky/dashboard/out/_next/static/chunks/pages/infra-abb7d744ecf15109.js +0 -1
- sky/dashboard/out/_next/static/chunks/pages/jobs/[job]-48dc8d67d4b60be1.js +0 -1
- sky/dashboard/out/_next/static/chunks/pages/jobs-73d5e0c369d00346.js +0 -16
- sky/dashboard/out/_next/static/chunks/pages/users-b8acf6e6735323a2.js +0 -1
- sky/dashboard/out/_next/static/chunks/pages/workspaces-5ed48b3201b998c8.js +0 -1
- sky/dashboard/out/_next/static/css/28558d57108b05ae.css +0 -3
- /sky/dashboard/out/_next/static/{7GEgRyZKRaSnYZCV1Jwol → Mx1iAbDQn1jMHh3UHmK3R}/_ssgManifest.js +0 -0
- /sky/dashboard/out/_next/static/chunks/pages/{_app-96a715a6fb01e228.js → _app-a631df412d8172de.js} +0 -0
- {skypilot_nightly-1.0.0.dev20250526.dist-info → skypilot_nightly-1.0.0.dev20250528.dist-info}/entry_points.txt +0 -0
- {skypilot_nightly-1.0.0.dev20250526.dist-info → skypilot_nightly-1.0.0.dev20250528.dist-info}/licenses/LICENSE +0 -0
- {skypilot_nightly-1.0.0.dev20250526.dist-info → skypilot_nightly-1.0.0.dev20250528.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/
|
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/ffd1cd601648c303.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/ffd1cd601648c303.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-deda68c926e8d0bc.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-87d061ee6ed71b28.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-e0e2335212e72357.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-a631df412d8172de.js" defer=""></script><script src="/dashboard/_next/static/chunks/9f96d65d-5a3e4af68c26849e.js" defer=""></script><script src="/dashboard/_next/static/chunks/173-7db8607cefc20f70.js" defer=""></script><script src="/dashboard/_next/static/chunks/121-8f55ee3fa6301784.js" defer=""></script><script src="/dashboard/_next/static/chunks/320-afea3ddcc5bd1c6c.js" defer=""></script><script src="/dashboard/_next/static/chunks/470-4d003c441839094d.js" defer=""></script><script src="/dashboard/_next/static/chunks/293-351268365226d251.js" defer=""></script><script src="/dashboard/_next/static/chunks/856-62b87c68917b08ed.js" defer=""></script><script src="/dashboard/_next/static/chunks/973-1a09cac61cfcc1e1.js" defer=""></script><script src="/dashboard/_next/static/chunks/236-d6900c828331f664.js" defer=""></script><script src="/dashboard/_next/static/chunks/843-256ec920f6d5f41f.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/workspaces/%5Bname%5D-9388e38fac73ee8f.js" defer=""></script><script src="/dashboard/_next/static/Mx1iAbDQn1jMHh3UHmK3R/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/Mx1iAbDQn1jMHh3UHmK3R/_ssgManifest.js" defer=""></script></head><body><div id="__next"><div>Loading...</div></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/workspaces/[name]","query":{},"buildId":"Mx1iAbDQn1jMHh3UHmK3R","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"/><link rel="preload" href="/dashboard/skypilot.svg" as="image" fetchpriority="high"/><meta name="next-head-count" content="3"/><link rel="preload" href="/dashboard/_next/static/css/28558d57108b05ae.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/28558d57108b05ae.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-deda68c926e8d0bc.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-87d061ee6ed71b28.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-e0e2335212e72357.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-96a715a6fb01e228.js" defer=""></script><script src="/dashboard/_next/static/chunks/9f96d65d-5a3e4af68c26849e.js" defer=""></script><script src="/dashboard/_next/static/chunks/573-f17bd89d9f9118b3.js" defer=""></script><script src="/dashboard/_next/static/chunks/488-50d843fdb5396d32.js" defer=""></script><script src="/dashboard/_next/static/chunks/498-d7722313e5e5b4e6.js" defer=""></script><script src="/dashboard/_next/static/chunks/480-5a0de8b6570ea105.js" defer=""></script><script src="/dashboard/_next/static/chunks/734-a6e01d7f98904741.js" defer=""></script><script src="/dashboard/_next/static/chunks/938-59956af3950b02ed.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/workspaces-5ed48b3201b998c8.js" defer=""></script><script src="/dashboard/_next/static/7GEgRyZKRaSnYZCV1Jwol/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/7GEgRyZKRaSnYZCV1Jwol/_ssgManifest.js" defer=""></script></head><body><div id="__next"><div class="min-h-screen bg-gray-50"><div class="fixed top-0 left-0 right-0 z-50 shadow-sm"><div class="fixed top-0 left-0 right-0 bg-white z-30 h-14 px-4 border-b border-gray-200 shadow-sm"><div class="flex items-center h-full"><div class="flex items-center space-x-4 mr-6"><a class="flex items-center px-1 pt-1 h-full" href="/dashboard"><div class="h-20 w-20 flex items-center justify-center"><img alt="SkyPilot Logo" fetchpriority="high" width="80" height="80" decoding="async" data-nimg="1" class="w-full h-full object-contain" style="color:transparent" src="/dashboard/skypilot.svg"/></div></a></div><div class="flex items-center space-x-2 md:space-x-4 mr-6"><a class="inline-flex items-center border-b-2 border-transparent hover:text-blue-600 px-1 pt-1 space-x-2" href="/dashboard/clusters"><svg class="w-4 h-4" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="20" height="8" x="2" y="2" rx="2" ry="2"></rect><rect width="20" height="8" x="2" y="14" rx="2" ry="2"></rect><line x1="6" x2="6.01" y1="6" y2="6"></line><line x1="6" x2="6.01" y1="18" y2="18"></line></svg><span>Clusters</span></a><a class="inline-flex items-center border-b-2 border-transparent hover:text-blue-600 px-1 pt-1 space-x-2" href="/dashboard/jobs"><svg class="w-4 h-4" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M16 20V4a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v16"></path><rect width="20" height="14" x="2" y="6" rx="2"></rect></svg><span>Jobs</span></a><div class="border-l border-gray-200 h-6 mx-1"></div><a class="inline-flex items-center border-b-2 border-transparent hover:text-blue-600 px-1 pt-1 space-x-2" href="/dashboard/infra"><svg class="w-4 h-4" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="4" y="4" width="16" height="16" rx="2" ry="2"></rect><rect x="9" y="9" width="6" height="6"></rect><line x1="9" y1="1" x2="9" y2="4"></line><line x1="15" y1="1" x2="15" y2="4"></line><line x1="9" y1="20" x2="9" y2="23"></line><line x1="15" y1="20" x2="15" y2="23"></line><line x1="20" y1="9" x2="23" y2="9"></line><line x1="20" y1="14" x2="23" y2="14"></line><line x1="1" y1="9" x2="4" y2="9"></line><line x1="1" y1="14" x2="4" y2="14"></line></svg><span>Infra</span></a><a class="inline-flex items-center border-b-2 border-transparent text-blue-600 px-1 pt-1 space-x-2" href="/dashboard/workspaces"><svg class="w-4 h-4" stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><g><path fill="none" d="M0 0h24v24H0z"></path><path d="M3 18.5V5a3 3 0 0 1 3-3h14a1 1 0 0 1 1 1v18a1 1 0 0 1-1 1H6.5A3.5 3.5 0 0 1 3 18.5zM19 20v-3H6.5a1.5 1.5 0 0 0 0 3H19zM10 4H6a1 1 0 0 0-1 1v10.337A3.486 3.486 0 0 1 6.5 15H19V4h-2v8l-3.5-2-3.5 2V4z"></path></g></svg><span>Workspaces</span></a><a class="inline-flex items-center border-b-2 border-transparent hover:text-blue-600 px-1 pt-1 space-x-2" href="/dashboard/users"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-users w-4 h-4"><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"></path><circle cx="9" cy="7" r="4"></circle><path d="M22 21v-2a4 4 0 0 0-3-3.87"></path><path d="M16 3.13a4 4 0 0 1 0 7.75"></path></svg><span>Users</span></a></div><div class="flex items-center space-x-1 ml-auto"><a href="https://skypilot.readthedocs.io/en/latest/" target="_blank" rel="noopener noreferrer" class="inline-flex items-center px-2 py-1 text-gray-600 hover:text-blue-600 transition-colors duration-150 cursor-pointer" title="Docs" tabindex="0"><span class="mr-1">Docs</span><svg class="w-3.5 h-3.5" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"></path><polyline points="15 3 21 3 21 9"></polyline><line x1="10" y1="14" x2="21" y2="3"></line></svg></a><div class="border-l border-gray-200 h-6 mx-1"></div><a href="https://github.com/skypilot-org/skypilot" target="_blank" rel="noopener noreferrer" class="inline-flex items-center justify-center p-2 rounded-full text-gray-600 hover:bg-gray-100 transition-colors duration-150 cursor-pointer" title="GitHub" tabindex="0"><svg class="w-5 h-5" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="currentColor"><path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"></path></svg></a><a href="https://slack.skypilot.co/" target="_blank" rel="noopener noreferrer" class="inline-flex items-center justify-center p-2 rounded-full text-gray-600 hover:bg-gray-100 transition-colors duration-150 cursor-pointer" title="Slack" tabindex="0"><svg class="w-5 h-5" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="currentColor"><path transform="scale(0.85) translate(1.8, 1.8)" d="M5.042 15.165a2.528 2.528 0 0 1-2.52 2.523A2.528 2.528 0 0 1 0 15.165a2.527 2.527 0 0 1 2.522-2.52h2.52v2.52zM6.313 15.165a2.527 2.527 0 0 1 2.521-2.52 2.527 2.527 0 0 1 2.521 2.52v6.313A2.528 2.528 0 0 1 8.834 24a2.528 2.528 0 0 1-2.521-2.522v-6.313zM8.834 5.042a2.528 2.528 0 0 1-2.521-2.52A2.528 2.528 0 0 1 8.834 0a2.528 2.528 0 0 1 2.521 2.522v2.52H8.834zM8.834 6.313a2.528 2.528 0 0 1 2.521 2.521 2.528 2.528 0 0 1-2.521 2.521H2.522A2.528 2.528 0 0 1 0 8.834a2.528 2.528 0 0 1 2.522-2.521h6.312zM18.956 8.834a2.528 2.528 0 0 1 2.522-2.521A2.528 2.528 0 0 1 24 8.834a2.528 2.528 0 0 1-2.522 2.521h-2.522V8.834zM17.688 8.834a2.528 2.528 0 0 1-2.523 2.521 2.527 2.527 0 0 1-2.52-2.521V2.522A2.527 2.527 0 0 1 15.165 0a2.528 2.528 0 0 1 2.523 2.522v6.312zM15.165 18.956a2.528 2.528 0 0 1 2.523 2.522A2.528 2.528 0 0 1 15.165 24a2.527 2.527 0 0 1-2.52-2.522v-2.522h2.52zM15.165 17.688a2.527 2.527 0 0 1-2.52-2.523 2.526 2.526 0 0 1 2.52-2.52h6.313A2.527 2.527 0 0 1 24 15.165a2.528 2.528 0 0 1-2.522 2.523h-6.313z"></path></svg></a><a href="https://github.com/skypilot-org/skypilot/issues/new" target="_blank" rel="noopener noreferrer" class="inline-flex items-center justify-center p-2 rounded-full text-gray-600 hover:bg-gray-100 transition-colors duration-150 cursor-pointer" title="Leave Feedback" tabindex="0"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-message-square w-5 h-5"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"></path></svg></a></div></div></div></div><div class="transition-all duration-200 ease-in-out min-h-screen" style="padding-top:56px"><main class="p-6"><div class="flex justify-center items-center h-64"><style data-emotion="css z01bqi animation-61bdi0">.css-z01bqi{display:inline-block;color:#1976d2;-webkit-animation:animation-61bdi0 1.4s linear infinite;animation:animation-61bdi0 1.4s linear infinite;}@-webkit-keyframes animation-61bdi0{0%{-webkit-transform:rotate(0deg);-moz-transform:rotate(0deg);-ms-transform:rotate(0deg);transform:rotate(0deg);}100%{-webkit-transform:rotate(360deg);-moz-transform:rotate(360deg);-ms-transform:rotate(360deg);transform:rotate(360deg);}}@keyframes animation-61bdi0{0%{-webkit-transform:rotate(0deg);-moz-transform:rotate(0deg);-ms-transform:rotate(0deg);transform:rotate(0deg);}100%{-webkit-transform:rotate(360deg);-moz-transform:rotate(360deg);-ms-transform:rotate(360deg);transform:rotate(360deg);}}</style><span class="MuiCircularProgress-root MuiCircularProgress-indeterminate MuiCircularProgress-colorPrimary css-z01bqi" style="width:40px;height:40px" role="progressbar"><style data-emotion="css 13o7eu2">.css-13o7eu2{display:block;}</style><svg class="MuiCircularProgress-svg css-13o7eu2" viewBox="22 22 44 44"><style data-emotion="css 14891ef animation-1p2h4ri">.css-14891ef{stroke:currentColor;stroke-dasharray:80px,200px;stroke-dashoffset:0;-webkit-animation:animation-1p2h4ri 1.4s ease-in-out infinite;animation:animation-1p2h4ri 1.4s ease-in-out infinite;}@-webkit-keyframes animation-1p2h4ri{0%{stroke-dasharray:1px,200px;stroke-dashoffset:0;}50%{stroke-dasharray:100px,200px;stroke-dashoffset:-15px;}100%{stroke-dasharray:100px,200px;stroke-dashoffset:-125px;}}@keyframes animation-1p2h4ri{0%{stroke-dasharray:1px,200px;stroke-dashoffset:0;}50%{stroke-dasharray:100px,200px;stroke-dashoffset:-15px;}100%{stroke-dasharray:100px,200px;stroke-dashoffset:-125px;}}</style><circle class="MuiCircularProgress-circle MuiCircularProgress-circleIndeterminate css-14891ef" cx="44" cy="44" r="20.2" fill="none" stroke-width="3.6"></circle></svg></span><span class="ml-2 text-gray-500">Loading workspaces...</span></div></main></div></div></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/workspaces","query":{},"buildId":"7GEgRyZKRaSnYZCV1Jwol","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"/><link rel="preload" href="/dashboard/skypilot.svg" as="image" fetchpriority="high"/><meta name="next-head-count" content="3"/><link rel="preload" href="/dashboard/_next/static/css/ffd1cd601648c303.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/ffd1cd601648c303.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-deda68c926e8d0bc.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-87d061ee6ed71b28.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-e0e2335212e72357.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-a631df412d8172de.js" defer=""></script><script src="/dashboard/_next/static/chunks/9f96d65d-5a3e4af68c26849e.js" defer=""></script><script src="/dashboard/_next/static/chunks/173-7db8607cefc20f70.js" defer=""></script><script src="/dashboard/_next/static/chunks/121-8f55ee3fa6301784.js" defer=""></script><script src="/dashboard/_next/static/chunks/320-afea3ddcc5bd1c6c.js" defer=""></script><script src="/dashboard/_next/static/chunks/470-4d003c441839094d.js" defer=""></script><script src="/dashboard/_next/static/chunks/293-351268365226d251.js" defer=""></script><script src="/dashboard/_next/static/chunks/856-62b87c68917b08ed.js" defer=""></script><script src="/dashboard/_next/static/chunks/973-1a09cac61cfcc1e1.js" defer=""></script><script src="/dashboard/_next/static/chunks/236-d6900c828331f664.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/workspaces-610c49ae3619ee85.js" defer=""></script><script src="/dashboard/_next/static/Mx1iAbDQn1jMHh3UHmK3R/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/Mx1iAbDQn1jMHh3UHmK3R/_ssgManifest.js" defer=""></script></head><body><div id="__next"><div class="min-h-screen bg-gray-50"><div class="fixed top-0 left-0 right-0 z-50 shadow-sm"><div class="fixed top-0 left-0 right-0 bg-white z-30 h-14 px-4 border-b border-gray-200 shadow-sm"><div class="flex items-center h-full"><div class="flex items-center space-x-4 mr-6"><a class="flex items-center px-1 pt-1 h-full" href="/dashboard"><div class="h-20 w-20 flex items-center justify-center"><img alt="SkyPilot Logo" fetchpriority="high" width="80" height="80" decoding="async" data-nimg="1" class="w-full h-full object-contain" style="color:transparent" src="/dashboard/skypilot.svg"/></div></a></div><div class="flex items-center space-x-2 md:space-x-4 mr-6"><a class="inline-flex items-center border-b-2 border-transparent hover:text-blue-600 px-1 pt-1 space-x-2" href="/dashboard/clusters"><svg class="w-4 h-4" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="20" height="8" x="2" y="2" rx="2" ry="2"></rect><rect width="20" height="8" x="2" y="14" rx="2" ry="2"></rect><line x1="6" x2="6.01" y1="6" y2="6"></line><line x1="6" x2="6.01" y1="18" y2="18"></line></svg><span>Clusters</span></a><a class="inline-flex items-center border-b-2 border-transparent hover:text-blue-600 px-1 pt-1 space-x-2" href="/dashboard/jobs"><svg class="w-4 h-4" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M16 20V4a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v16"></path><rect width="20" height="14" x="2" y="6" rx="2"></rect></svg><span>Jobs</span></a><div class="border-l border-gray-200 h-6 mx-1"></div><a class="inline-flex items-center border-b-2 border-transparent hover:text-blue-600 px-1 pt-1 space-x-2" href="/dashboard/infra"><svg class="w-4 h-4" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="4" y="4" width="16" height="16" rx="2" ry="2"></rect><rect x="9" y="9" width="6" height="6"></rect><line x1="9" y1="1" x2="9" y2="4"></line><line x1="15" y1="1" x2="15" y2="4"></line><line x1="9" y1="20" x2="9" y2="23"></line><line x1="15" y1="20" x2="15" y2="23"></line><line x1="20" y1="9" x2="23" y2="9"></line><line x1="20" y1="14" x2="23" y2="14"></line><line x1="1" y1="9" x2="4" y2="9"></line><line x1="1" y1="14" x2="4" y2="14"></line></svg><span>Infra</span></a><a class="inline-flex items-center border-b-2 border-transparent text-blue-600 px-1 pt-1 space-x-2" href="/dashboard/workspaces"><svg class="w-4 h-4" stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><g><path fill="none" d="M0 0h24v24H0z"></path><path d="M3 18.5V5a3 3 0 0 1 3-3h14a1 1 0 0 1 1 1v18a1 1 0 0 1-1 1H6.5A3.5 3.5 0 0 1 3 18.5zM19 20v-3H6.5a1.5 1.5 0 0 0 0 3H19zM10 4H6a1 1 0 0 0-1 1v10.337A3.486 3.486 0 0 1 6.5 15H19V4h-2v8l-3.5-2-3.5 2V4z"></path></g></svg><span>Workspaces</span></a><a class="inline-flex items-center border-b-2 border-transparent hover:text-blue-600 px-1 pt-1 space-x-2" href="/dashboard/users"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-users w-4 h-4"><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"></path><circle cx="9" cy="7" r="4"></circle><path d="M22 21v-2a4 4 0 0 0-3-3.87"></path><path d="M16 3.13a4 4 0 0 1 0 7.75"></path></svg><span>Users</span></a></div><div class="flex items-center space-x-1 ml-auto"><a href="https://skypilot.readthedocs.io/en/latest/" target="_blank" rel="noopener noreferrer" class="inline-flex items-center px-2 py-1 text-gray-600 hover:text-blue-600 transition-colors duration-150 cursor-pointer" title="Docs" tabindex="0"><span class="mr-1">Docs</span><svg class="w-3.5 h-3.5" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"></path><polyline points="15 3 21 3 21 9"></polyline><line x1="10" y1="14" x2="21" y2="3"></line></svg></a><a href="https://github.com/skypilot-org/skypilot" target="_blank" rel="noopener noreferrer" class="inline-flex items-center justify-center p-2 rounded-full text-gray-600 hover:bg-gray-100 transition-colors duration-150 cursor-pointer" title="GitHub" tabindex="0"><svg class="w-5 h-5" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="currentColor"><path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"></path></svg></a><a href="https://slack.skypilot.co/" target="_blank" rel="noopener noreferrer" class="inline-flex items-center justify-center p-2 rounded-full text-gray-600 hover:bg-gray-100 transition-colors duration-150 cursor-pointer" title="Slack" tabindex="0"><svg class="w-5 h-5" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="currentColor"><path transform="scale(0.85) translate(1.8, 1.8)" d="M5.042 15.165a2.528 2.528 0 0 1-2.52 2.523A2.528 2.528 0 0 1 0 15.165a2.527 2.527 0 0 1 2.522-2.52h2.52v2.52zM6.313 15.165a2.527 2.527 0 0 1 2.521-2.52 2.527 2.527 0 0 1 2.521 2.52v6.313A2.528 2.528 0 0 1 8.834 24a2.528 2.528 0 0 1-2.521-2.522v-6.313zM8.834 5.042a2.528 2.528 0 0 1-2.521-2.52A2.528 2.528 0 0 1 8.834 0a2.528 2.528 0 0 1 2.521 2.522v2.52H8.834zM8.834 6.313a2.528 2.528 0 0 1 2.521 2.521 2.528 2.528 0 0 1-2.521 2.521H2.522A2.528 2.528 0 0 1 0 8.834a2.528 2.528 0 0 1 2.522-2.521h6.312zM18.956 8.834a2.528 2.528 0 0 1 2.522-2.521A2.528 2.528 0 0 1 24 8.834a2.528 2.528 0 0 1-2.522 2.521h-2.522V8.834zM17.688 8.834a2.528 2.528 0 0 1-2.523 2.521 2.527 2.527 0 0 1-2.52-2.521V2.522A2.527 2.527 0 0 1 15.165 0a2.528 2.528 0 0 1 2.523 2.522v6.312zM15.165 18.956a2.528 2.528 0 0 1 2.523 2.522A2.528 2.528 0 0 1 15.165 24a2.527 2.527 0 0 1-2.52-2.522v-2.522h2.52zM15.165 17.688a2.527 2.527 0 0 1-2.52-2.523 2.526 2.526 0 0 1 2.52-2.52h6.313A2.527 2.527 0 0 1 24 15.165a2.528 2.528 0 0 1-2.522 2.523h-6.313z"></path></svg></a><a href="https://github.com/skypilot-org/skypilot/issues/new" target="_blank" rel="noopener noreferrer" class="inline-flex items-center justify-center p-2 rounded-full text-gray-600 hover:bg-gray-100 transition-colors duration-150 cursor-pointer" title="Leave Feedback" tabindex="0"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-message-square w-5 h-5"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"></path></svg></a><div class="border-l border-gray-200 h-6"></div><a class="inline-flex items-center justify-center p-2 rounded-full transition-colors duration-150 cursor-pointer text-gray-600 hover:bg-gray-100" title="Configuration" tabindex="0" href="/dashboard/config"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-settings w-5 h-5"><path d="M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z"></path><circle cx="12" cy="12" r="3"></circle></svg></a></div></div></div></div><div class="transition-all duration-200 ease-in-out min-h-screen" style="padding-top:56px"><main class="p-6"><div class="flex justify-center items-center h-64"><style data-emotion="css z01bqi animation-61bdi0">.css-z01bqi{display:inline-block;color:#1976d2;-webkit-animation:animation-61bdi0 1.4s linear infinite;animation:animation-61bdi0 1.4s linear infinite;}@-webkit-keyframes animation-61bdi0{0%{-webkit-transform:rotate(0deg);-moz-transform:rotate(0deg);-ms-transform:rotate(0deg);transform:rotate(0deg);}100%{-webkit-transform:rotate(360deg);-moz-transform:rotate(360deg);-ms-transform:rotate(360deg);transform:rotate(360deg);}}@keyframes animation-61bdi0{0%{-webkit-transform:rotate(0deg);-moz-transform:rotate(0deg);-ms-transform:rotate(0deg);transform:rotate(0deg);}100%{-webkit-transform:rotate(360deg);-moz-transform:rotate(360deg);-ms-transform:rotate(360deg);transform:rotate(360deg);}}</style><span class="MuiCircularProgress-root MuiCircularProgress-indeterminate MuiCircularProgress-colorPrimary css-z01bqi" style="width:40px;height:40px" role="progressbar"><style data-emotion="css 13o7eu2">.css-13o7eu2{display:block;}</style><svg class="MuiCircularProgress-svg css-13o7eu2" viewBox="22 22 44 44"><style data-emotion="css 14891ef animation-1p2h4ri">.css-14891ef{stroke:currentColor;stroke-dasharray:80px,200px;stroke-dashoffset:0;-webkit-animation:animation-1p2h4ri 1.4s ease-in-out infinite;animation:animation-1p2h4ri 1.4s ease-in-out infinite;}@-webkit-keyframes animation-1p2h4ri{0%{stroke-dasharray:1px,200px;stroke-dashoffset:0;}50%{stroke-dasharray:100px,200px;stroke-dashoffset:-15px;}100%{stroke-dasharray:100px,200px;stroke-dashoffset:-125px;}}@keyframes animation-1p2h4ri{0%{stroke-dasharray:1px,200px;stroke-dashoffset:0;}50%{stroke-dasharray:100px,200px;stroke-dashoffset:-15px;}100%{stroke-dasharray:100px,200px;stroke-dashoffset:-125px;}}</style><circle class="MuiCircularProgress-circle MuiCircularProgress-circleIndeterminate css-14891ef" cx="44" cy="44" r="20.2" fill="none" stroke-width="3.6"></circle></svg></span><span class="ml-2 text-gray-500">Loading workspaces...</span></div></main></div></div></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/workspaces","query":{},"buildId":"Mx1iAbDQn1jMHh3UHmK3R","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
|
sky/global_user_state.py
CHANGED
@@ -10,6 +10,7 @@ import json
|
|
10
10
|
import os
|
11
11
|
import pathlib
|
12
12
|
import pickle
|
13
|
+
import re
|
13
14
|
import time
|
14
15
|
import typing
|
15
16
|
from typing import Any, Dict, List, Optional, Set, Tuple
|
@@ -18,6 +19,7 @@ import uuid
|
|
18
19
|
import sqlalchemy
|
19
20
|
from sqlalchemy import exc as sqlalchemy_exc
|
20
21
|
from sqlalchemy import orm
|
22
|
+
from sqlalchemy.dialects import postgresql
|
21
23
|
from sqlalchemy.dialects import sqlite
|
22
24
|
from sqlalchemy.ext import declarative
|
23
25
|
|
@@ -43,7 +45,14 @@ _ENABLED_CLOUDS_KEY_PREFIX = 'enabled_clouds_'
|
|
43
45
|
_DB_PATH = os.path.expanduser('~/.sky/state.db')
|
44
46
|
pathlib.Path(_DB_PATH).parents[0].mkdir(parents=True, exist_ok=True)
|
45
47
|
|
46
|
-
|
48
|
+
if os.environ.get(constants.SKYPILOT_API_SERVER_DB_URL_ENV_VAR):
|
49
|
+
# If SKYPILOT_API_SERVER_DB_URL_ENV_VAR is set, use it as the database URI.
|
50
|
+
logger.debug(
|
51
|
+
f'using db URI from {constants.SKYPILOT_API_SERVER_DB_URL_ENV_VAR}')
|
52
|
+
_SQLALCHEMY_ENGINE = sqlalchemy.create_engine(
|
53
|
+
os.environ.get(constants.SKYPILOT_API_SERVER_DB_URL_ENV_VAR))
|
54
|
+
else:
|
55
|
+
_SQLALCHEMY_ENGINE = sqlalchemy.create_engine('sqlite:///' + _DB_PATH)
|
47
56
|
|
48
57
|
Base = declarative.declarative_base()
|
49
58
|
|
@@ -125,6 +134,26 @@ cluster_history_table = sqlalchemy.Table(
|
|
125
134
|
)
|
126
135
|
|
127
136
|
|
137
|
+
def _glob_to_similar(glob_pattern):
|
138
|
+
"""Converts a glob pattern to a PostgreSQL LIKE pattern."""
|
139
|
+
|
140
|
+
# Escape special LIKE characters that are not special in glob
|
141
|
+
glob_pattern = glob_pattern.replace('%', '\\%').replace('_', '\\_')
|
142
|
+
|
143
|
+
# Convert glob wildcards to LIKE wildcards
|
144
|
+
like_pattern = glob_pattern.replace('*', '%').replace('?', '_')
|
145
|
+
|
146
|
+
# Handle character classes, including negation
|
147
|
+
def replace_char_class(match):
|
148
|
+
group = match.group(0)
|
149
|
+
if group.startswith('[!'):
|
150
|
+
return '[^' + group[2:-1] + ']'
|
151
|
+
return group
|
152
|
+
|
153
|
+
like_pattern = re.sub(r'\[(!)?.*?\]', replace_char_class, like_pattern)
|
154
|
+
return like_pattern
|
155
|
+
|
156
|
+
|
128
157
|
def create_table():
|
129
158
|
# Enable WAL mode to avoid locking issues.
|
130
159
|
# See: issue #1441 and PR #1509
|
@@ -152,31 +181,52 @@ def create_table():
|
|
152
181
|
# the latest version of SkyPilot.
|
153
182
|
with orm.Session(_SQLALCHEMY_ENGINE) as session:
|
154
183
|
# Add autostop column to clusters table
|
155
|
-
db_utils.add_column_to_table_sqlalchemy(session,
|
156
|
-
'
|
184
|
+
db_utils.add_column_to_table_sqlalchemy(session,
|
185
|
+
'clusters',
|
186
|
+
'autostop',
|
187
|
+
sqlalchemy.Integer(),
|
188
|
+
default_statement='DEFAULT -1')
|
157
189
|
|
158
|
-
db_utils.add_column_to_table_sqlalchemy(
|
159
|
-
|
190
|
+
db_utils.add_column_to_table_sqlalchemy(
|
191
|
+
session,
|
192
|
+
'clusters',
|
193
|
+
'metadata',
|
194
|
+
sqlalchemy.Text(),
|
195
|
+
default_statement='DEFAULT \'{}\'')
|
160
196
|
|
161
|
-
db_utils.add_column_to_table_sqlalchemy(session,
|
162
|
-
'
|
197
|
+
db_utils.add_column_to_table_sqlalchemy(session,
|
198
|
+
'clusters',
|
199
|
+
'to_down',
|
200
|
+
sqlalchemy.Integer(),
|
201
|
+
default_statement='DEFAULT 0')
|
163
202
|
|
164
203
|
# The cloud identity that created the cluster.
|
165
|
-
db_utils.add_column_to_table_sqlalchemy(
|
166
|
-
|
204
|
+
db_utils.add_column_to_table_sqlalchemy(
|
205
|
+
session,
|
206
|
+
'clusters',
|
207
|
+
'owner',
|
208
|
+
sqlalchemy.Text(),
|
209
|
+
default_statement='DEFAULT NULL')
|
167
210
|
|
168
|
-
db_utils.add_column_to_table_sqlalchemy(
|
169
|
-
|
170
|
-
|
211
|
+
db_utils.add_column_to_table_sqlalchemy(
|
212
|
+
session,
|
213
|
+
'clusters',
|
214
|
+
'cluster_hash',
|
215
|
+
sqlalchemy.Text(),
|
216
|
+
default_statement='DEFAULT NULL')
|
171
217
|
|
172
|
-
db_utils.add_column_to_table_sqlalchemy(
|
173
|
-
|
174
|
-
|
218
|
+
db_utils.add_column_to_table_sqlalchemy(
|
219
|
+
session,
|
220
|
+
'clusters',
|
221
|
+
'storage_mounts_metadata',
|
222
|
+
sqlalchemy.LargeBinary(),
|
223
|
+
default_statement='DEFAULT NULL')
|
175
224
|
db_utils.add_column_to_table_sqlalchemy(
|
176
225
|
session,
|
177
226
|
'clusters',
|
178
227
|
'cluster_ever_up',
|
179
|
-
|
228
|
+
sqlalchemy.Integer(),
|
229
|
+
default_statement='DEFAULT 0',
|
180
230
|
# Set the value to 1 so that all the existing clusters before #2977
|
181
231
|
# are considered as ever up, i.e:
|
182
232
|
# existing cluster's default (null) -> 1;
|
@@ -185,28 +235,39 @@ def create_table():
|
|
185
235
|
# clusters were never really UP, setting it to 1 means they won't be
|
186
236
|
# auto-deleted during any failover.
|
187
237
|
value_to_replace_existing_entries=1)
|
188
|
-
db_utils.add_column_to_table_sqlalchemy(session, 'clusters',
|
189
|
-
'status_updated_at',
|
190
|
-
'INTEGER DEFAULT null')
|
191
238
|
db_utils.add_column_to_table_sqlalchemy(
|
192
239
|
session,
|
193
240
|
'clusters',
|
194
|
-
'
|
195
|
-
|
241
|
+
'status_updated_at',
|
242
|
+
sqlalchemy.Integer(),
|
243
|
+
default_statement='DEFAULT NULL')
|
244
|
+
db_utils.add_column_to_table_sqlalchemy(
|
245
|
+
session,
|
246
|
+
'clusters',
|
247
|
+
'user_hasha',
|
248
|
+
sqlalchemy.Text(),
|
249
|
+
default_statement='DEFAULT NULL',
|
196
250
|
value_to_replace_existing_entries=common_utils.get_user_hash())
|
197
|
-
db_utils.add_column_to_table_sqlalchemy(
|
198
|
-
|
199
|
-
|
251
|
+
db_utils.add_column_to_table_sqlalchemy(
|
252
|
+
session,
|
253
|
+
'clusters',
|
254
|
+
'config_hash',
|
255
|
+
sqlalchemy.Text(),
|
256
|
+
default_statement='DEFAULT NULL')
|
200
257
|
|
201
|
-
db_utils.add_column_to_table_sqlalchemy(
|
202
|
-
|
203
|
-
|
258
|
+
db_utils.add_column_to_table_sqlalchemy(
|
259
|
+
session,
|
260
|
+
'cluster_history',
|
261
|
+
'user_hash',
|
262
|
+
sqlalchemy.Text(),
|
263
|
+
default_statement='DEFAULT NULL')
|
204
264
|
|
205
265
|
db_utils.add_column_to_table_sqlalchemy(
|
206
266
|
session,
|
207
267
|
'clusters',
|
208
268
|
'workspace',
|
209
|
-
|
269
|
+
sqlalchemy.Text(),
|
270
|
+
default_statement='DEFAULT \'default\'',
|
210
271
|
value_to_replace_existing_entries=constants.
|
211
272
|
SKYPILOT_DEFAULT_WORKSPACE)
|
212
273
|
session.commit()
|
@@ -223,20 +284,18 @@ def add_or_update_user(user: models.User):
|
|
223
284
|
with orm.Session(_SQLALCHEMY_ENGINE) as session:
|
224
285
|
if (_SQLALCHEMY_ENGINE.dialect.name ==
|
225
286
|
db_utils.SQLAlchemyDialect.SQLITE.value):
|
226
|
-
|
227
|
-
name=user.name)
|
228
|
-
do_update_stmt = insert_stmnt.on_conflict_do_update(
|
229
|
-
index_elements=[user_table.c.id],
|
230
|
-
set_={user_table.c.name: user.name})
|
231
|
-
session.execute(do_update_stmt)
|
287
|
+
insert_func = sqlite.insert
|
232
288
|
elif (_SQLALCHEMY_ENGINE.dialect.name ==
|
233
289
|
db_utils.SQLAlchemyDialect.POSTGRESQL.value):
|
234
|
-
|
235
|
-
session.rollback()
|
236
|
-
raise ValueError('Unsupported database dialect')
|
290
|
+
insert_func = postgresql.insert
|
237
291
|
else:
|
238
|
-
session.rollback()
|
239
292
|
raise ValueError('Unsupported database dialect')
|
293
|
+
insert_stmnt = insert_func(user_table).values(id=user.id,
|
294
|
+
name=user.name)
|
295
|
+
do_update_stmt = insert_stmnt.on_conflict_do_update(
|
296
|
+
index_elements=[user_table.c.id],
|
297
|
+
set_={user_table.c.name: user.name})
|
298
|
+
session.execute(do_update_stmt)
|
240
299
|
session.commit()
|
241
300
|
|
242
301
|
|
@@ -348,76 +407,67 @@ def add_or_update_cluster(cluster_name: str,
|
|
348
407
|
|
349
408
|
if (_SQLALCHEMY_ENGINE.dialect.name ==
|
350
409
|
db_utils.SQLAlchemyDialect.SQLITE.value):
|
351
|
-
|
352
|
-
name=cluster_name,
|
353
|
-
**conditional_values,
|
354
|
-
handle=handle,
|
355
|
-
status=status.value,
|
356
|
-
# set metadata to server default ('{}')
|
357
|
-
# set owner to server default (null)
|
358
|
-
cluster_hash=cluster_hash,
|
359
|
-
# set storage_mounts_metadata to server default (null)
|
360
|
-
status_updated_at=status_updated_at,
|
361
|
-
)
|
362
|
-
do_update_stmt = insert_stmnt.on_conflict_do_update(
|
363
|
-
index_elements=[cluster_table.c.name],
|
364
|
-
set_={
|
365
|
-
**conditional_values,
|
366
|
-
cluster_table.c.handle: handle,
|
367
|
-
cluster_table.c.status: status.value,
|
368
|
-
# do not update metadata value
|
369
|
-
# do not update owner value
|
370
|
-
cluster_table.c.cluster_hash: cluster_hash,
|
371
|
-
# do not update storage_mounts_metadata
|
372
|
-
cluster_table.c.status_updated_at: status_updated_at,
|
373
|
-
# do not update user_hash
|
374
|
-
})
|
375
|
-
session.execute(do_update_stmt)
|
410
|
+
insert_func = sqlite.insert
|
376
411
|
elif (_SQLALCHEMY_ENGINE.dialect.name ==
|
377
412
|
db_utils.SQLAlchemyDialect.POSTGRESQL.value):
|
378
|
-
|
379
|
-
session.rollback()
|
380
|
-
raise ValueError('Unsupported database dialect')
|
413
|
+
insert_func = postgresql.insert
|
381
414
|
else:
|
382
415
|
session.rollback()
|
383
416
|
raise ValueError('Unsupported database dialect')
|
384
417
|
|
418
|
+
insert_stmnt = insert_func(cluster_table).values(
|
419
|
+
name=cluster_name,
|
420
|
+
**conditional_values,
|
421
|
+
handle=handle,
|
422
|
+
status=status.value,
|
423
|
+
# set metadata to server default ('{}')
|
424
|
+
# set owner to server default (null)
|
425
|
+
cluster_hash=cluster_hash,
|
426
|
+
# set storage_mounts_metadata to server default (null)
|
427
|
+
status_updated_at=status_updated_at,
|
428
|
+
)
|
429
|
+
do_update_stmt = insert_stmnt.on_conflict_do_update(
|
430
|
+
index_elements=[cluster_table.c.name],
|
431
|
+
set_={
|
432
|
+
**conditional_values,
|
433
|
+
cluster_table.c.handle: handle,
|
434
|
+
cluster_table.c.status: status.value,
|
435
|
+
# do not update metadata value
|
436
|
+
# do not update owner value
|
437
|
+
cluster_table.c.cluster_hash: cluster_hash,
|
438
|
+
# do not update storage_mounts_metadata
|
439
|
+
cluster_table.c.status_updated_at: status_updated_at,
|
440
|
+
# do not update user_hash
|
441
|
+
})
|
442
|
+
session.execute(do_update_stmt)
|
443
|
+
|
385
444
|
# Modify cluster history table
|
386
445
|
launched_nodes = getattr(cluster_handle, 'launched_nodes', None)
|
387
446
|
launched_resources = getattr(cluster_handle, 'launched_resources', None)
|
388
447
|
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
session.execute(do_update_stmt)
|
413
|
-
elif (_SQLALCHEMY_ENGINE.dialect.name ==
|
414
|
-
db_utils.SQLAlchemyDialect.POSTGRESQL.value):
|
415
|
-
# TODO(syang) support postgres dialect
|
416
|
-
session.rollback()
|
417
|
-
raise ValueError('Unsupported database dialect')
|
418
|
-
else:
|
419
|
-
session.rollback()
|
420
|
-
raise ValueError('Unsupported database dialect')
|
448
|
+
insert_stmnt = insert_func(cluster_history_table).values(
|
449
|
+
cluster_hash=cluster_hash,
|
450
|
+
name=cluster_name,
|
451
|
+
num_nodes=launched_nodes,
|
452
|
+
requested_resources=pickle.dumps(requested_resources),
|
453
|
+
launched_resources=pickle.dumps(launched_resources),
|
454
|
+
usage_intervals=pickle.dumps(usage_intervals),
|
455
|
+
user_hash=user_hash)
|
456
|
+
do_update_stmt = insert_stmnt.on_conflict_do_update(
|
457
|
+
index_elements=[cluster_history_table.c.cluster_hash],
|
458
|
+
set_={
|
459
|
+
cluster_history_table.c.name: cluster_name,
|
460
|
+
cluster_history_table.c.num_nodes: launched_nodes,
|
461
|
+
cluster_history_table.c.requested_resources:
|
462
|
+
pickle.dumps(requested_resources),
|
463
|
+
cluster_history_table.c.launched_resources:
|
464
|
+
pickle.dumps(launched_resources),
|
465
|
+
cluster_history_table.c.usage_intervals:
|
466
|
+
pickle.dumps(usage_intervals),
|
467
|
+
cluster_history_table.c.user_hash: user_hash
|
468
|
+
})
|
469
|
+
session.execute(do_update_stmt)
|
470
|
+
|
421
471
|
session.commit()
|
422
472
|
|
423
473
|
|
@@ -504,9 +554,9 @@ def get_glob_cluster_names(cluster_name: str) -> List[str]:
|
|
504
554
|
cluster_table.c.name.op('GLOB')(cluster_name)).all()
|
505
555
|
elif (_SQLALCHEMY_ENGINE.dialect.name ==
|
506
556
|
db_utils.SQLAlchemyDialect.POSTGRESQL.value):
|
507
|
-
|
508
|
-
|
509
|
-
|
557
|
+
rows = session.query(cluster_table).filter(
|
558
|
+
cluster_table.c.name.op('SIMILAR TO')(
|
559
|
+
_glob_to_similar(cluster_name))).all()
|
510
560
|
else:
|
511
561
|
raise ValueError('Unsupported database dialect')
|
512
562
|
return [row.name for row in rows]
|
@@ -741,6 +791,7 @@ def get_cluster_from_name(
|
|
741
791
|
'config_hash': row.config_hash,
|
742
792
|
'workspace': row.workspace,
|
743
793
|
}
|
794
|
+
|
744
795
|
return record
|
745
796
|
|
746
797
|
|
@@ -849,21 +900,19 @@ def set_enabled_clouds(enabled_clouds: List[str],
|
|
849
900
|
with orm.Session(_SQLALCHEMY_ENGINE) as session:
|
850
901
|
if (_SQLALCHEMY_ENGINE.dialect.name ==
|
851
902
|
db_utils.SQLAlchemyDialect.SQLITE.value):
|
852
|
-
|
853
|
-
key=_get_enabled_clouds_key(cloud_capability, workspace),
|
854
|
-
value=json.dumps(enabled_clouds))
|
855
|
-
do_update_stmt = insert_stmnt.on_conflict_do_update(
|
856
|
-
index_elements=[config_table.c.key],
|
857
|
-
set_={config_table.c.value: json.dumps(enabled_clouds)})
|
858
|
-
session.execute(do_update_stmt)
|
903
|
+
insert_func = sqlite.insert
|
859
904
|
elif (_SQLALCHEMY_ENGINE.dialect.name ==
|
860
905
|
db_utils.SQLAlchemyDialect.POSTGRESQL.value):
|
861
|
-
|
862
|
-
session.rollback()
|
863
|
-
raise ValueError('Unsupported database dialect')
|
906
|
+
insert_func = postgresql.insert
|
864
907
|
else:
|
865
|
-
session.rollback()
|
866
908
|
raise ValueError('Unsupported database dialect')
|
909
|
+
insert_stmnt = insert_func(config_table).values(
|
910
|
+
key=_get_enabled_clouds_key(cloud_capability, workspace),
|
911
|
+
value=json.dumps(enabled_clouds))
|
912
|
+
do_update_stmt = insert_stmnt.on_conflict_do_update(
|
913
|
+
index_elements=[config_table.c.key],
|
914
|
+
set_={config_table.c.value: json.dumps(enabled_clouds)})
|
915
|
+
session.execute(do_update_stmt)
|
867
916
|
session.commit()
|
868
917
|
|
869
918
|
|
@@ -888,29 +937,27 @@ def add_or_update_storage(storage_name: str,
|
|
888
937
|
with orm.Session(_SQLALCHEMY_ENGINE) as session:
|
889
938
|
if (_SQLALCHEMY_ENGINE.dialect.name ==
|
890
939
|
db_utils.SQLAlchemyDialect.SQLITE.value):
|
891
|
-
|
892
|
-
name=storage_name,
|
893
|
-
handle=handle,
|
894
|
-
last_use=last_use,
|
895
|
-
launched_at=storage_launched_at,
|
896
|
-
status=storage_status.value)
|
897
|
-
do_update_stmt = insert_stmnt.on_conflict_do_update(
|
898
|
-
index_elements=[storage_table.c.name],
|
899
|
-
set_={
|
900
|
-
storage_table.c.handle: handle,
|
901
|
-
storage_table.c.last_use: last_use,
|
902
|
-
storage_table.c.launched_at: storage_launched_at,
|
903
|
-
storage_table.c.status: storage_status.value
|
904
|
-
})
|
905
|
-
session.execute(do_update_stmt)
|
940
|
+
insert_func = sqlite.insert
|
906
941
|
elif (_SQLALCHEMY_ENGINE.dialect.name ==
|
907
942
|
db_utils.SQLAlchemyDialect.POSTGRESQL.value):
|
908
|
-
|
909
|
-
session.rollback()
|
910
|
-
raise ValueError('Unsupported database dialect')
|
943
|
+
insert_func = postgresql.insert
|
911
944
|
else:
|
912
|
-
session.rollback()
|
913
945
|
raise ValueError('Unsupported database dialect')
|
946
|
+
insert_stmnt = insert_func(storage_table).values(
|
947
|
+
name=storage_name,
|
948
|
+
handle=handle,
|
949
|
+
last_use=last_use,
|
950
|
+
launched_at=storage_launched_at,
|
951
|
+
status=storage_status.value)
|
952
|
+
do_update_stmt = insert_stmnt.on_conflict_do_update(
|
953
|
+
index_elements=[storage_table.c.name],
|
954
|
+
set_={
|
955
|
+
storage_table.c.handle: handle,
|
956
|
+
storage_table.c.last_use: last_use,
|
957
|
+
storage_table.c.launched_at: storage_launched_at,
|
958
|
+
storage_table.c.status: storage_status.value
|
959
|
+
})
|
960
|
+
session.execute(do_update_stmt)
|
914
961
|
session.commit()
|
915
962
|
|
916
963
|
|
@@ -973,9 +1020,9 @@ def get_glob_storage_name(storage_name: str) -> List[str]:
|
|
973
1020
|
storage_table.c.name.op('GLOB')(storage_name)).all()
|
974
1021
|
elif (_SQLALCHEMY_ENGINE.dialect.name ==
|
975
1022
|
db_utils.SQLAlchemyDialect.POSTGRESQL.value):
|
976
|
-
|
977
|
-
|
978
|
-
|
1023
|
+
rows = session.query(storage_table).filter(
|
1024
|
+
storage_table.c.name.op('SIMILAR TO')(
|
1025
|
+
_glob_to_similar(storage_name))).all()
|
979
1026
|
else:
|
980
1027
|
raise ValueError('Unsupported database dialect')
|
981
1028
|
return [row.name for row in rows]
|
@@ -1525,7 +1525,7 @@ def is_kubeconfig_exec_auth(
|
|
1525
1525
|
return False, None
|
1526
1526
|
|
1527
1527
|
# Get active context and user from kubeconfig using k8s api
|
1528
|
-
all_contexts, current_context =
|
1528
|
+
all_contexts, current_context = kubernetes.list_kube_config_contexts()
|
1529
1529
|
context_obj = current_context
|
1530
1530
|
if context is not None:
|
1531
1531
|
for c in all_contexts:
|
@@ -1581,7 +1581,7 @@ def get_current_kube_config_context_name() -> Optional[str]:
|
|
1581
1581
|
"""
|
1582
1582
|
k8s = kubernetes.kubernetes
|
1583
1583
|
try:
|
1584
|
-
_, current_context =
|
1584
|
+
_, current_context = kubernetes.list_kube_config_contexts()
|
1585
1585
|
return current_context['name']
|
1586
1586
|
except k8s.config.config_exception.ConfigException:
|
1587
1587
|
return None
|
@@ -1617,7 +1617,7 @@ def get_all_kube_context_names() -> List[str]:
|
|
1617
1617
|
k8s = kubernetes.kubernetes
|
1618
1618
|
context_names = []
|
1619
1619
|
try:
|
1620
|
-
all_contexts, _ =
|
1620
|
+
all_contexts, _ = kubernetes.list_kube_config_contexts()
|
1621
1621
|
# all_contexts will always have at least one context. If kubeconfig
|
1622
1622
|
# does not have any contexts defined, it will raise ConfigException.
|
1623
1623
|
context_names = [context['name'] for context in all_contexts]
|
@@ -1660,7 +1660,7 @@ def get_kube_config_context_namespace(
|
|
1660
1660
|
return f.read().strip()
|
1661
1661
|
# If not in-cluster, get the namespace from kubeconfig
|
1662
1662
|
try:
|
1663
|
-
contexts, current_context =
|
1663
|
+
contexts, current_context = kubernetes.list_kube_config_contexts()
|
1664
1664
|
if context_name is None:
|
1665
1665
|
context = current_context
|
1666
1666
|
else:
|
sky/server/constants.py
CHANGED
@@ -7,7 +7,7 @@ from sky.skylet import constants
|
|
7
7
|
# API server version, whenever there is a change in API server that requires a
|
8
8
|
# restart of the local API server or error out when the client does not match
|
9
9
|
# the server version.
|
10
|
-
API_VERSION = '
|
10
|
+
API_VERSION = '6'
|
11
11
|
|
12
12
|
# Prefix for API request names.
|
13
13
|
REQUEST_NAME_PREFIX = 'sky.'
|
sky/server/requests/payloads.py
CHANGED
@@ -72,6 +72,8 @@ def request_body_env_vars() -> dict:
|
|
72
72
|
|
73
73
|
def get_override_skypilot_config_from_client() -> Dict[str, Any]:
|
74
74
|
"""Returns the override configs from the client."""
|
75
|
+
if annotations.is_on_api_server:
|
76
|
+
return {}
|
75
77
|
config = skypilot_config.to_dict()
|
76
78
|
# Remove the API server config, as we should not specify the SkyPilot
|
77
79
|
# server endpoint on the server side. This avoids the warning at
|
@@ -134,6 +136,12 @@ class CheckBody(RequestBody):
|
|
134
136
|
workspace: Optional[str] = None
|
135
137
|
|
136
138
|
|
139
|
+
class EnabledCloudsBody(RequestBody):
|
140
|
+
"""The request body for the enabled clouds endpoint."""
|
141
|
+
workspace: Optional[str] = None
|
142
|
+
expand: bool = False
|
143
|
+
|
144
|
+
|
137
145
|
class DagRequestBody(RequestBody):
|
138
146
|
"""Request body base class for endpoints with a dag."""
|
139
147
|
dag: str
|
@@ -533,11 +541,6 @@ class UploadZipFileResponse(pydantic.BaseModel):
|
|
533
541
|
missing_chunks: Optional[List[str]] = None
|
534
542
|
|
535
543
|
|
536
|
-
class EnabledCloudsBody(RequestBody):
|
537
|
-
"""The request body for the enabled clouds endpoint."""
|
538
|
-
workspace: Optional[str] = None
|
539
|
-
|
540
|
-
|
541
544
|
class UpdateWorkspaceBody(RequestBody):
|
542
545
|
"""The request body for updating a specific workspace configuration."""
|
543
546
|
workspace_name: str = '' # Will be set from path parameter
|
@@ -553,3 +556,13 @@ class CreateWorkspaceBody(RequestBody):
|
|
553
556
|
class DeleteWorkspaceBody(RequestBody):
|
554
557
|
"""The request body for deleting a workspace."""
|
555
558
|
workspace_name: str
|
559
|
+
|
560
|
+
|
561
|
+
class UpdateConfigBody(RequestBody):
|
562
|
+
"""The request body for updating the entire SkyPilot configuration."""
|
563
|
+
config: Dict[str, Any]
|
564
|
+
|
565
|
+
|
566
|
+
class GetConfigBody(RequestBody):
|
567
|
+
"""The request body for getting the entire SkyPilot configuration."""
|
568
|
+
pass
|