skypilot-nightly 1.0.0.dev20250709__py3-none-any.whl → 1.0.0.dev20250711__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/backends/cloud_vm_ray_backend.py +6 -4
- sky/clouds/kubernetes.py +137 -23
- sky/core.py +3 -1
- sky/dashboard/out/404.html +1 -1
- sky/dashboard/out/_next/static/chunks/1871-3a0f047988be65cd.js +6 -0
- sky/dashboard/out/_next/static/chunks/8969-13bb52ce3cffa4e3.js +1 -0
- sky/dashboard/out/_next/static/chunks/{webpack-9a81ea998672c303.js → webpack-60070a62f55486a6.js} +1 -1
- sky/dashboard/out/_next/static/css/6cbd41a88d2e9e1c.css +3 -0
- sky/dashboard/out/_next/static/{EqELoF4IXcALfWVihInou → ldZFQWCiYX_vZnIfB_o8S}/_buildManifest.js +1 -1
- 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 -1
- sky/dashboard/out/index.html +1 -1
- sky/dashboard/out/infra/[context].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/volumes.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 +10 -11
- sky/jobs/constants.py +1 -1
- sky/jobs/controller.py +7 -0
- sky/jobs/server/core.py +2 -1
- sky/jobs/server/utils.py +81 -0
- sky/jobs/state.py +58 -40
- sky/jobs/utils.py +45 -6
- sky/provision/kubernetes/instance.py +17 -0
- sky/provision/kubernetes/utils.py +134 -0
- sky/provision/provisioner.py +20 -0
- sky/skylet/constants.py +1 -6
- sky/skylet/job_lib.py +30 -8
- sky/skypilot_config.py +8 -3
- sky/task.py +17 -0
- sky/templates/kubernetes-ray.yml.j2 +298 -10
- sky/users/permission.py +18 -1
- sky/users/token_service.py +25 -3
- sky/utils/common_utils.py +13 -0
- sky/utils/db_utils.py +16 -0
- sky/utils/schemas.py +6 -0
- sky/utils/ux_utils.py +2 -4
- {skypilot_nightly-1.0.0.dev20250709.dist-info → skypilot_nightly-1.0.0.dev20250711.dist-info}/METADATA +1 -1
- {skypilot_nightly-1.0.0.dev20250709.dist-info → skypilot_nightly-1.0.0.dev20250711.dist-info}/RECORD +55 -54
- sky/dashboard/out/_next/static/chunks/1871-80dea41717729fa5.js +0 -6
- sky/dashboard/out/_next/static/chunks/8969-909d53833da080cb.js +0 -1
- sky/dashboard/out/_next/static/css/0da6afe66176678a.css +0 -3
- /sky/dashboard/out/_next/static/chunks/pages/{_app-a37b06ddb64521fd.js → _app-e6e82dc8abb50c4f.js} +0 -0
- /sky/dashboard/out/_next/static/chunks/pages/clusters/{[cluster]-1159f362b960e2b8.js → [cluster]-0fbfb1dd0b08c90c.js} +0 -0
- /sky/dashboard/out/_next/static/chunks/pages/{clusters-9744c271a1642f76.js → clusters-102d169e87913ba1.js} +0 -0
- /sky/dashboard/out/_next/static/{EqELoF4IXcALfWVihInou → ldZFQWCiYX_vZnIfB_o8S}/_ssgManifest.js +0 -0
- {skypilot_nightly-1.0.0.dev20250709.dist-info → skypilot_nightly-1.0.0.dev20250711.dist-info}/WHEEL +0 -0
- {skypilot_nightly-1.0.0.dev20250709.dist-info → skypilot_nightly-1.0.0.dev20250711.dist-info}/entry_points.txt +0 -0
- {skypilot_nightly-1.0.0.dev20250709.dist-info → skypilot_nightly-1.0.0.dev20250711.dist-info}/licenses/LICENSE +0 -0
- {skypilot_nightly-1.0.0.dev20250709.dist-info → skypilot_nightly-1.0.0.dev20250711.dist-info}/top_level.txt +0 -0
sky/dashboard/out/clusters.html
CHANGED
@@ -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/6cbd41a88d2e9e1c.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/6cbd41a88d2e9e1c.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-60070a62f55486a6.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-efc06c2733009cd3.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-c0a4f1ea606d48d2.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-e6e82dc8abb50c4f.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/clusters-102d169e87913ba1.js" defer=""></script><script src="/dashboard/_next/static/ldZFQWCiYX_vZnIfB_o8S/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/ldZFQWCiYX_vZnIfB_o8S/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/clusters","query":{},"buildId":"ldZFQWCiYX_vZnIfB_o8S","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
|
sky/dashboard/out/config.html
CHANGED
@@ -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/6cbd41a88d2e9e1c.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/6cbd41a88d2e9e1c.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-60070a62f55486a6.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-efc06c2733009cd3.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-c0a4f1ea606d48d2.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-e6e82dc8abb50c4f.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/config-a2673b256b6d416f.js" defer=""></script><script src="/dashboard/_next/static/ldZFQWCiYX_vZnIfB_o8S/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/ldZFQWCiYX_vZnIfB_o8S/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/config","query":{},"buildId":"ldZFQWCiYX_vZnIfB_o8S","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
|
sky/dashboard/out/index.html
CHANGED
@@ -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/6cbd41a88d2e9e1c.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/6cbd41a88d2e9e1c.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-60070a62f55486a6.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-efc06c2733009cd3.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-c0a4f1ea606d48d2.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-e6e82dc8abb50c4f.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/index-927ddeebe57a8ac3.js" defer=""></script><script src="/dashboard/_next/static/ldZFQWCiYX_vZnIfB_o8S/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/ldZFQWCiYX_vZnIfB_o8S/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/","query":{},"buildId":"ldZFQWCiYX_vZnIfB_o8S","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/
|
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/6cbd41a88d2e9e1c.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/6cbd41a88d2e9e1c.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-60070a62f55486a6.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-efc06c2733009cd3.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-c0a4f1ea606d48d2.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-e6e82dc8abb50c4f.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/infra/%5Bcontext%5D-8b0809f59034d509.js" defer=""></script><script src="/dashboard/_next/static/ldZFQWCiYX_vZnIfB_o8S/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/ldZFQWCiYX_vZnIfB_o8S/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/infra/[context]","query":{},"buildId":"ldZFQWCiYX_vZnIfB_o8S","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
|
sky/dashboard/out/infra.html
CHANGED
@@ -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/6cbd41a88d2e9e1c.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/6cbd41a88d2e9e1c.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-60070a62f55486a6.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-efc06c2733009cd3.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-c0a4f1ea606d48d2.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-e6e82dc8abb50c4f.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/infra-ae9d2f705ce582c9.js" defer=""></script><script src="/dashboard/_next/static/ldZFQWCiYX_vZnIfB_o8S/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/ldZFQWCiYX_vZnIfB_o8S/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/infra","query":{},"buildId":"ldZFQWCiYX_vZnIfB_o8S","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/
|
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/6cbd41a88d2e9e1c.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/6cbd41a88d2e9e1c.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-60070a62f55486a6.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-efc06c2733009cd3.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-c0a4f1ea606d48d2.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-e6e82dc8abb50c4f.js" defer=""></script><script src="/dashboard/_next/static/chunks/616-162f3033ffcd3d31.js" defer=""></script><script src="/dashboard/_next/static/chunks/5230-df791914b54d91d9.js" defer=""></script><script src="/dashboard/_next/static/chunks/5739-5ea3ffa10fc884f2.js" defer=""></script><script src="/dashboard/_next/static/chunks/1664-d65361e92b85e786.js" defer=""></script><script src="/dashboard/_next/static/chunks/804-9f5e98ce84d46bdd.js" defer=""></script><script src="/dashboard/_next/static/chunks/1272-1ef0bf0237faccdb.js" defer=""></script><script src="/dashboard/_next/static/chunks/6989-6ff4e45dfb49d11d.js" defer=""></script><script src="/dashboard/_next/static/chunks/3698-52ad1ca228faa776.js" defer=""></script><script src="/dashboard/_next/static/chunks/9470-21d059a1dfa03f61.js" defer=""></script><script src="/dashboard/_next/static/chunks/8969-13bb52ce3cffa4e3.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/jobs/%5Bjob%5D-c4d5cfac7fbc0668.js" defer=""></script><script src="/dashboard/_next/static/ldZFQWCiYX_vZnIfB_o8S/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/ldZFQWCiYX_vZnIfB_o8S/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/jobs/[job]","query":{},"buildId":"ldZFQWCiYX_vZnIfB_o8S","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
|
sky/dashboard/out/jobs.html
CHANGED
@@ -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/6cbd41a88d2e9e1c.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/6cbd41a88d2e9e1c.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-60070a62f55486a6.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-efc06c2733009cd3.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-c0a4f1ea606d48d2.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-e6e82dc8abb50c4f.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/jobs-5bbdc71878f0a068.js" defer=""></script><script src="/dashboard/_next/static/ldZFQWCiYX_vZnIfB_o8S/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/ldZFQWCiYX_vZnIfB_o8S/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/jobs","query":{},"buildId":"ldZFQWCiYX_vZnIfB_o8S","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
|
sky/dashboard/out/users.html
CHANGED
@@ -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/6cbd41a88d2e9e1c.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/6cbd41a88d2e9e1c.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-60070a62f55486a6.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-efc06c2733009cd3.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-c0a4f1ea606d48d2.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-e6e82dc8abb50c4f.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/users-cd43fb3c122eedde.js" defer=""></script><script src="/dashboard/_next/static/ldZFQWCiYX_vZnIfB_o8S/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/ldZFQWCiYX_vZnIfB_o8S/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/users","query":{},"buildId":"ldZFQWCiYX_vZnIfB_o8S","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
|
sky/dashboard/out/volumes.html
CHANGED
@@ -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/6cbd41a88d2e9e1c.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/6cbd41a88d2e9e1c.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-60070a62f55486a6.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-efc06c2733009cd3.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-c0a4f1ea606d48d2.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-e6e82dc8abb50c4f.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/volumes-4ebf6484f7216387.js" defer=""></script><script src="/dashboard/_next/static/ldZFQWCiYX_vZnIfB_o8S/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/ldZFQWCiYX_vZnIfB_o8S/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/volumes","query":{},"buildId":"ldZFQWCiYX_vZnIfB_o8S","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/
|
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/6cbd41a88d2e9e1c.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/6cbd41a88d2e9e1c.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-60070a62f55486a6.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-efc06c2733009cd3.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-c0a4f1ea606d48d2.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-e6e82dc8abb50c4f.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/workspace/new-5629d4e551dba1ee.js" defer=""></script><script src="/dashboard/_next/static/ldZFQWCiYX_vZnIfB_o8S/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/ldZFQWCiYX_vZnIfB_o8S/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/workspace/new","query":{},"buildId":"ldZFQWCiYX_vZnIfB_o8S","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/
|
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/6cbd41a88d2e9e1c.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/6cbd41a88d2e9e1c.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-60070a62f55486a6.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-efc06c2733009cd3.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-c0a4f1ea606d48d2.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-e6e82dc8abb50c4f.js" defer=""></script><script src="/dashboard/_next/static/chunks/616-162f3033ffcd3d31.js" defer=""></script><script src="/dashboard/_next/static/chunks/5230-df791914b54d91d9.js" defer=""></script><script src="/dashboard/_next/static/chunks/5739-5ea3ffa10fc884f2.js" defer=""></script><script src="/dashboard/_next/static/chunks/1664-d65361e92b85e786.js" defer=""></script><script src="/dashboard/_next/static/chunks/804-9f5e98ce84d46bdd.js" defer=""></script><script src="/dashboard/_next/static/chunks/1272-1ef0bf0237faccdb.js" defer=""></script><script src="/dashboard/_next/static/chunks/3947-b059261d6fa88a1f.js" defer=""></script><script src="/dashboard/_next/static/chunks/6989-6ff4e45dfb49d11d.js" defer=""></script><script src="/dashboard/_next/static/chunks/3698-52ad1ca228faa776.js" defer=""></script><script src="/dashboard/_next/static/chunks/9470-21d059a1dfa03f61.js" defer=""></script><script src="/dashboard/_next/static/chunks/6990-d0dc765474fa0eca.js" defer=""></script><script src="/dashboard/_next/static/chunks/8969-13bb52ce3cffa4e3.js" defer=""></script><script src="/dashboard/_next/static/chunks/1043-1b39779691bb4030.js" defer=""></script><script src="/dashboard/_next/static/chunks/6601-fcfad0ddf92ec7ab.js" defer=""></script><script src="/dashboard/_next/static/chunks/938-044ad21de8b4626b.js" defer=""></script><script src="/dashboard/_next/static/chunks/1141-726e5a3f00b67185.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/workspaces/%5Bname%5D-7c0187f43757a548.js" defer=""></script><script src="/dashboard/_next/static/ldZFQWCiYX_vZnIfB_o8S/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/ldZFQWCiYX_vZnIfB_o8S/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/workspaces/[name]","query":{},"buildId":"ldZFQWCiYX_vZnIfB_o8S","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/
|
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/6cbd41a88d2e9e1c.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/6cbd41a88d2e9e1c.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-60070a62f55486a6.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-efc06c2733009cd3.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-c0a4f1ea606d48d2.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-e6e82dc8abb50c4f.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/workspaces-06bde99155fa6292.js" defer=""></script><script src="/dashboard/_next/static/ldZFQWCiYX_vZnIfB_o8S/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/ldZFQWCiYX_vZnIfB_o8S/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/workspaces","query":{},"buildId":"ldZFQWCiYX_vZnIfB_o8S","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
|
sky/global_user_state.py
CHANGED
@@ -220,17 +220,16 @@ def _glob_to_similar(glob_pattern):
|
|
220
220
|
return like_pattern
|
221
221
|
|
222
222
|
|
223
|
-
def create_table():
|
223
|
+
def create_table(engine: sqlalchemy.engine.Engine):
|
224
224
|
# Enable WAL mode to avoid locking issues.
|
225
225
|
# See: issue #1441 and PR #1509
|
226
226
|
# https://github.com/microsoft/WSL/issues/2395
|
227
227
|
# TODO(romilb): We do not enable WAL for WSL because of known issue in WSL.
|
228
228
|
# This may cause the database locked problem from WSL issue #1441.
|
229
|
-
if (
|
230
|
-
== db_utils.SQLAlchemyDialect.SQLITE.value and
|
229
|
+
if (engine.dialect.name == db_utils.SQLAlchemyDialect.SQLITE.value and
|
231
230
|
not common_utils.is_wsl()):
|
232
231
|
try:
|
233
|
-
with orm.Session(
|
232
|
+
with orm.Session(engine) as session:
|
234
233
|
session.execute(sqlalchemy.text('PRAGMA journal_mode=WAL'))
|
235
234
|
session.commit()
|
236
235
|
except sqlalchemy_exc.OperationalError as e:
|
@@ -240,12 +239,12 @@ def create_table():
|
|
240
239
|
# is not critical and is likely to be enabled by other processes.
|
241
240
|
|
242
241
|
# Create tables if they don't exist
|
243
|
-
Base.metadata
|
242
|
+
db_utils.add_tables_to_db_sqlalchemy(Base.metadata, engine)
|
244
243
|
|
245
244
|
# For backward compatibility.
|
246
245
|
# TODO(zhwu): Remove this function after all users have migrated to
|
247
246
|
# the latest version of SkyPilot.
|
248
|
-
with orm.Session(
|
247
|
+
with orm.Session(engine) as session:
|
249
248
|
# Add autostop column to clusters table
|
250
249
|
db_utils.add_column_to_table_sqlalchemy(session,
|
251
250
|
'clusters',
|
@@ -391,15 +390,15 @@ def initialize_and_get_db() -> sqlalchemy.engine.Engine:
|
|
391
390
|
conn_string = skypilot_config.get_nested(('db',), None)
|
392
391
|
if conn_string:
|
393
392
|
logger.debug(f'using db URI from {conn_string}')
|
394
|
-
|
395
|
-
|
393
|
+
engine = sqlalchemy.create_engine(conn_string,
|
394
|
+
poolclass=sqlalchemy.NullPool)
|
396
395
|
else:
|
397
396
|
db_path = os.path.expanduser('~/.sky/state.db')
|
398
397
|
pathlib.Path(db_path).parents[0].mkdir(parents=True,
|
399
398
|
exist_ok=True)
|
400
|
-
|
401
|
-
|
402
|
-
|
399
|
+
engine = sqlalchemy.create_engine('sqlite:///' + db_path)
|
400
|
+
create_table(engine)
|
401
|
+
_SQLALCHEMY_ENGINE = engine
|
403
402
|
return _SQLALCHEMY_ENGINE
|
404
403
|
|
405
404
|
|
sky/jobs/constants.py
CHANGED
@@ -47,7 +47,7 @@ JOBS_CLUSTER_NAME_PREFIX_LENGTH = 25
|
|
47
47
|
# The version of the lib files that jobs/utils use. Whenever there is an API
|
48
48
|
# change for the jobs/utils, we need to bump this version and update
|
49
49
|
# job.utils.ManagedJobCodeGen to handle the version update.
|
50
|
-
MANAGED_JOBS_VERSION =
|
50
|
+
MANAGED_JOBS_VERSION = 7
|
51
51
|
|
52
52
|
# The command for setting up the jobs dashboard on the controller. It firstly
|
53
53
|
# checks if the systemd services are available, and if not (e.g., Kubernetes
|
sky/jobs/controller.py
CHANGED
@@ -14,6 +14,13 @@ from typing import Optional, Tuple
|
|
14
14
|
|
15
15
|
import filelock
|
16
16
|
|
17
|
+
# This import ensures backward compatibility. Controller processes may not have
|
18
|
+
# imported this module initially, but will attempt to import it during job
|
19
|
+
# termination on the fly. If a job was launched with an old SkyPilot runtime
|
20
|
+
# and a new job is launched with a newer runtime, the old job's termination
|
21
|
+
# will try to import code from a different SkyPilot runtime, causing exceptions.
|
22
|
+
# pylint: disable=unused-import
|
23
|
+
from sky import core
|
17
24
|
from sky import exceptions
|
18
25
|
from sky import sky_logging
|
19
26
|
from sky.backends import backend_utils
|
sky/jobs/server/core.py
CHANGED
@@ -110,7 +110,8 @@ def _maybe_submit_job_locally(prefix: str, dag: 'sky.Dag') -> Optional[int]:
|
|
110
110
|
resources_str = backend_utils.get_task_resources_str(
|
111
111
|
task, is_managed_job=True)
|
112
112
|
managed_job_state.set_pending(consolidation_mode_job_id, task_id,
|
113
|
-
task.name, resources_str
|
113
|
+
task.name, resources_str,
|
114
|
+
task.metadata_json)
|
114
115
|
return consolidation_mode_job_id
|
115
116
|
|
116
117
|
|
sky/jobs/server/utils.py
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
"""Utility functions for managed jobs."""
|
2
|
+
from sky import backends
|
3
|
+
from sky import sky_logging
|
4
|
+
from sky.backends import backend_utils
|
5
|
+
from sky.jobs import utils as managed_job_utils
|
6
|
+
from sky.skylet import constants as skylet_constants
|
7
|
+
from sky.utils import controller_utils
|
8
|
+
|
9
|
+
logger = sky_logging.init_logger(__name__)
|
10
|
+
|
11
|
+
|
12
|
+
def check_version_mismatch_and_non_terminal_jobs() -> None:
|
13
|
+
"""Check if controller has version mismatch and non-terminal jobs exist.
|
14
|
+
|
15
|
+
Raises:
|
16
|
+
ValueError: If there's a version mismatch and non-terminal jobs exist.
|
17
|
+
sky.exceptions.ClusterNotUpError: If the controller is not accessible.
|
18
|
+
"""
|
19
|
+
# Get the current local SKYLET_VERSION
|
20
|
+
local_version = skylet_constants.SKYLET_VERSION
|
21
|
+
|
22
|
+
# Get controller handle (works the same in both normal and
|
23
|
+
# consolidation mode)
|
24
|
+
jobs_controller_type = controller_utils.Controllers.JOBS_CONTROLLER
|
25
|
+
handle = backend_utils.is_controller_accessible(
|
26
|
+
controller=jobs_controller_type,
|
27
|
+
stopped_message='Jobs controller is not running.')
|
28
|
+
|
29
|
+
backend = backend_utils.get_backend_from_handle(handle)
|
30
|
+
assert isinstance(backend, backends.CloudVmRayBackend)
|
31
|
+
|
32
|
+
# Get controller version and raw job table
|
33
|
+
code = managed_job_utils.ManagedJobCodeGen.get_version_and_job_table()
|
34
|
+
|
35
|
+
returncode, output, stderr = backend.run_on_head(handle,
|
36
|
+
code,
|
37
|
+
require_outputs=True,
|
38
|
+
stream_logs=False,
|
39
|
+
separate_stderr=True)
|
40
|
+
|
41
|
+
if returncode != 0:
|
42
|
+
logger.error(output + stderr)
|
43
|
+
raise ValueError('Failed to check controller version and jobs with '
|
44
|
+
f'returncode: {returncode}.\n{output + stderr}')
|
45
|
+
|
46
|
+
# Parse the output to extract controller version (split only on first
|
47
|
+
# newline)
|
48
|
+
output_parts = output.strip().split('\n', 1)
|
49
|
+
|
50
|
+
# Extract controller version from first line
|
51
|
+
if len(output_parts) < 2 or not output_parts[0].startswith(
|
52
|
+
'controller_version:'):
|
53
|
+
raise ValueError(
|
54
|
+
f'Expected controller version in first line, got: {output}')
|
55
|
+
|
56
|
+
controller_version = output_parts[0].split(':', 1)[1]
|
57
|
+
|
58
|
+
# Rest is job table payload (preserving any newlines within it)
|
59
|
+
job_table_payload = output_parts[1]
|
60
|
+
|
61
|
+
# Process locally: check version match and filter non-terminal jobs
|
62
|
+
version_matches = controller_version == local_version
|
63
|
+
|
64
|
+
# Load and filter jobs locally using existing method
|
65
|
+
jobs = managed_job_utils.load_managed_job_queue(job_table_payload)
|
66
|
+
non_terminal_jobs = [job for job in jobs if not job['status'].is_terminal()]
|
67
|
+
has_non_terminal_jobs = len(non_terminal_jobs) > 0
|
68
|
+
|
69
|
+
if not version_matches and has_non_terminal_jobs:
|
70
|
+
# Format job table locally using the same method as queue()
|
71
|
+
formatted_job_table = managed_job_utils.format_job_table(
|
72
|
+
non_terminal_jobs, show_all=False, show_user=False)
|
73
|
+
|
74
|
+
error_msg = (
|
75
|
+
f'Controller SKYLET_VERSION ({controller_version}) does not match '
|
76
|
+
f'current version ({local_version}), and there are non-terminal '
|
77
|
+
'jobs on the controller. Please wait for all jobs to complete or '
|
78
|
+
'cancel them before launching new jobs with the updated version.'
|
79
|
+
f'\n\nCurrent non-terminal jobs:\n{formatted_job_table}')
|
80
|
+
|
81
|
+
raise ValueError(error_msg)
|
sky/jobs/state.py
CHANGED
@@ -77,6 +77,7 @@ spot_table = sqlalchemy.Table(
|
|
77
77
|
sqlalchemy.Column('task_name', sqlalchemy.Text),
|
78
78
|
sqlalchemy.Column('specs', sqlalchemy.Text),
|
79
79
|
sqlalchemy.Column('local_log_file', sqlalchemy.Text, server_default=None),
|
80
|
+
sqlalchemy.Column('metadata', sqlalchemy.Text, server_default='{}'),
|
80
81
|
)
|
81
82
|
|
82
83
|
job_info_table = sqlalchemy.Table(
|
@@ -111,17 +112,16 @@ ha_recovery_script_table = sqlalchemy.Table(
|
|
111
112
|
)
|
112
113
|
|
113
114
|
|
114
|
-
def create_table():
|
115
|
+
def create_table(engine: sqlalchemy.engine.Engine):
|
115
116
|
# Enable WAL mode to avoid locking issues.
|
116
117
|
# See: issue #3863, #1441 and PR #1509
|
117
118
|
# https://github.com/microsoft/WSL/issues/2395
|
118
119
|
# TODO(romilb): We do not enable WAL for WSL because of known issue in WSL.
|
119
120
|
# This may cause the database locked problem from WSL issue #1441.
|
120
|
-
if (
|
121
|
-
== db_utils.SQLAlchemyDialect.SQLITE.value and
|
121
|
+
if (engine.dialect.name == db_utils.SQLAlchemyDialect.SQLITE.value and
|
122
122
|
not common_utils.is_wsl()):
|
123
123
|
try:
|
124
|
-
with orm.Session(
|
124
|
+
with orm.Session(engine) as session:
|
125
125
|
session.execute(sqlalchemy.text('PRAGMA journal_mode=WAL'))
|
126
126
|
session.commit()
|
127
127
|
except sqlalchemy_exc.OperationalError as e:
|
@@ -131,10 +131,10 @@ def create_table():
|
|
131
131
|
# is not critical and is likely to be enabled by other processes.
|
132
132
|
|
133
133
|
# Create tables if they don't exist
|
134
|
-
Base.metadata
|
134
|
+
db_utils.add_tables_to_db_sqlalchemy(Base.metadata, engine)
|
135
135
|
|
136
136
|
# Backward compatibility: add columns that not exist in older databases
|
137
|
-
with orm.Session(
|
137
|
+
with orm.Session(engine) as session:
|
138
138
|
db_utils.add_column_to_table_sqlalchemy(session, 'spot',
|
139
139
|
'failure_reason',
|
140
140
|
sqlalchemy.Text())
|
@@ -170,6 +170,14 @@ def create_table():
|
|
170
170
|
sqlalchemy.Text(),
|
171
171
|
default_statement='DEFAULT NULL')
|
172
172
|
|
173
|
+
db_utils.add_column_to_table_sqlalchemy(
|
174
|
+
session,
|
175
|
+
'spot',
|
176
|
+
'metadata',
|
177
|
+
sqlalchemy.Text(),
|
178
|
+
default_statement='DEFAULT \'{}\'',
|
179
|
+
value_to_replace_existing_entries='{}')
|
180
|
+
|
173
181
|
db_utils.add_column_to_table_sqlalchemy(session, 'job_info',
|
174
182
|
'schedule_state',
|
175
183
|
sqlalchemy.Text())
|
@@ -219,15 +227,15 @@ def initialize_and_get_db() -> sqlalchemy.engine.Engine:
|
|
219
227
|
conn_string = skypilot_config.get_nested(('db',), None)
|
220
228
|
if conn_string:
|
221
229
|
logger.debug(f'using db URI from {conn_string}')
|
222
|
-
|
223
|
-
|
230
|
+
engine = sqlalchemy.create_engine(conn_string,
|
231
|
+
poolclass=sqlalchemy.NullPool)
|
224
232
|
else:
|
225
233
|
db_path = os.path.expanduser('~/.sky/spot_jobs.db')
|
226
234
|
pathlib.Path(db_path).parents[0].mkdir(parents=True,
|
227
235
|
exist_ok=True)
|
228
|
-
|
229
|
-
|
230
|
-
|
236
|
+
engine = sqlalchemy.create_engine('sqlite:///' + db_path)
|
237
|
+
create_table(engine)
|
238
|
+
_SQLALCHEMY_ENGINE = engine
|
231
239
|
return _SQLALCHEMY_ENGINE
|
232
240
|
|
233
241
|
|
@@ -273,6 +281,7 @@ def _get_jobs_dict(r: 'row.RowMapping') -> Dict[str, Any]:
|
|
273
281
|
'task_name': r['task_name'],
|
274
282
|
'specs': r['specs'],
|
275
283
|
'local_log_file': r['local_log_file'],
|
284
|
+
'metadata': r['metadata'],
|
276
285
|
# columns from job_info table (some may be None for legacy jobs)
|
277
286
|
'_job_info_job_id': r[job_info_table.c.spot_job_id
|
278
287
|
], # ambiguous, use table.column
|
@@ -560,7 +569,13 @@ def set_job_info_without_job_id(name: str, workspace: str,
|
|
560
569
|
|
561
570
|
|
562
571
|
@_init_db
|
563
|
-
def set_pending(
|
572
|
+
def set_pending(
|
573
|
+
job_id: int,
|
574
|
+
task_id: int,
|
575
|
+
task_name: str,
|
576
|
+
resources_str: str,
|
577
|
+
metadata: str,
|
578
|
+
):
|
564
579
|
"""Set the task to pending state."""
|
565
580
|
assert _SQLALCHEMY_ENGINE is not None
|
566
581
|
with orm.Session(_SQLALCHEMY_ENGINE) as session:
|
@@ -570,6 +585,7 @@ def set_pending(job_id: int, task_id: int, task_name: str, resources_str: str):
|
|
570
585
|
task_id=task_id,
|
571
586
|
task_name=task_name,
|
572
587
|
resources=resources_str,
|
588
|
+
metadata=metadata,
|
573
589
|
status=ManagedJobStatus.PENDING.value,
|
574
590
|
))
|
575
591
|
session.commit()
|
@@ -1195,38 +1211,40 @@ def get_managed_jobs(job_id: Optional[int] = None) -> List[Dict[str, Any]]:
|
|
1195
1211
|
# Note: we will get the user_hash here, but don't try to call
|
1196
1212
|
# global_user_state.get_user() on it. This runs on the controller, which may
|
1197
1213
|
# not have the user info. Prefer to do it on the API server side.
|
1214
|
+
query = sqlalchemy.select(spot_table, job_info_table).select_from(
|
1215
|
+
spot_table.outerjoin(
|
1216
|
+
job_info_table,
|
1217
|
+
spot_table.c.spot_job_id == job_info_table.c.spot_job_id))
|
1218
|
+
if job_id is not None:
|
1219
|
+
query = query.where(spot_table.c.spot_job_id == job_id)
|
1220
|
+
query = query.order_by(spot_table.c.spot_job_id.desc(),
|
1221
|
+
spot_table.c.task_id.asc())
|
1222
|
+
rows = None
|
1198
1223
|
with orm.Session(_SQLALCHEMY_ENGINE) as session:
|
1199
|
-
query = sqlalchemy.select(spot_table, job_info_table).select_from(
|
1200
|
-
spot_table.outerjoin(
|
1201
|
-
job_info_table,
|
1202
|
-
spot_table.c.spot_job_id == job_info_table.c.spot_job_id))
|
1203
|
-
if job_id is not None:
|
1204
|
-
query = query.where(spot_table.c.spot_job_id == job_id)
|
1205
|
-
query = query.order_by(spot_table.c.spot_job_id.desc(),
|
1206
|
-
spot_table.c.task_id.asc())
|
1207
1224
|
rows = session.execute(query).fetchall()
|
1208
|
-
|
1209
|
-
|
1210
|
-
|
1211
|
-
|
1212
|
-
|
1213
|
-
|
1214
|
-
|
1215
|
-
|
1216
|
-
|
1217
|
-
|
1218
|
-
|
1219
|
-
|
1220
|
-
|
1221
|
-
|
1222
|
-
|
1223
|
-
|
1224
|
-
|
1225
|
-
else:
|
1225
|
+
jobs = []
|
1226
|
+
for row in rows:
|
1227
|
+
job_dict = _get_jobs_dict(row._mapping) # pylint: disable=protected-access
|
1228
|
+
job_dict['status'] = ManagedJobStatus(job_dict['status'])
|
1229
|
+
job_dict['schedule_state'] = ManagedJobScheduleState(
|
1230
|
+
job_dict['schedule_state'])
|
1231
|
+
if job_dict['job_name'] is None:
|
1232
|
+
job_dict['job_name'] = job_dict['task_name']
|
1233
|
+
job_dict['metadata'] = json.loads(job_dict['metadata'])
|
1234
|
+
|
1235
|
+
# Add user YAML content for managed jobs.
|
1236
|
+
yaml_path = job_dict.get('original_user_yaml_path')
|
1237
|
+
if yaml_path:
|
1238
|
+
try:
|
1239
|
+
with open(yaml_path, 'r', encoding='utf-8') as f:
|
1240
|
+
job_dict['user_yaml'] = f.read()
|
1241
|
+
except (FileNotFoundError, IOError, OSError):
|
1226
1242
|
job_dict['user_yaml'] = None
|
1243
|
+
else:
|
1244
|
+
job_dict['user_yaml'] = None
|
1227
1245
|
|
1228
|
-
|
1229
|
-
|
1246
|
+
jobs.append(job_dict)
|
1247
|
+
return jobs
|
1230
1248
|
|
1231
1249
|
|
1232
1250
|
@_init_db
|