skypilot-nightly 1.0.0.dev20250509__py3-none-any.whl → 1.0.0.dev20251107__py3-none-any.whl

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

Potentially problematic release.


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

Files changed (512) hide show
  1. sky/__init__.py +22 -6
  2. sky/adaptors/aws.py +25 -7
  3. sky/adaptors/common.py +24 -1
  4. sky/adaptors/coreweave.py +278 -0
  5. sky/adaptors/do.py +8 -2
  6. sky/adaptors/hyperbolic.py +8 -0
  7. sky/adaptors/kubernetes.py +149 -18
  8. sky/adaptors/nebius.py +170 -17
  9. sky/adaptors/primeintellect.py +1 -0
  10. sky/adaptors/runpod.py +68 -0
  11. sky/adaptors/seeweb.py +167 -0
  12. sky/adaptors/shadeform.py +89 -0
  13. sky/admin_policy.py +187 -4
  14. sky/authentication.py +179 -225
  15. sky/backends/__init__.py +4 -2
  16. sky/backends/backend.py +22 -9
  17. sky/backends/backend_utils.py +1299 -380
  18. sky/backends/cloud_vm_ray_backend.py +1715 -518
  19. sky/backends/docker_utils.py +1 -1
  20. sky/backends/local_docker_backend.py +11 -6
  21. sky/backends/wheel_utils.py +37 -9
  22. sky/{clouds/service_catalog → catalog}/__init__.py +21 -19
  23. sky/{clouds/service_catalog → catalog}/aws_catalog.py +27 -8
  24. sky/{clouds/service_catalog → catalog}/azure_catalog.py +10 -7
  25. sky/{clouds/service_catalog → catalog}/common.py +89 -48
  26. sky/{clouds/service_catalog → catalog}/cudo_catalog.py +8 -5
  27. sky/{clouds/service_catalog → catalog}/data_fetchers/analyze.py +1 -1
  28. sky/{clouds/service_catalog → catalog}/data_fetchers/fetch_aws.py +30 -40
  29. sky/{clouds/service_catalog → catalog}/data_fetchers/fetch_cudo.py +38 -38
  30. sky/{clouds/service_catalog → catalog}/data_fetchers/fetch_gcp.py +42 -15
  31. sky/catalog/data_fetchers/fetch_hyperbolic.py +136 -0
  32. sky/{clouds/service_catalog → catalog}/data_fetchers/fetch_lambda_cloud.py +1 -0
  33. sky/catalog/data_fetchers/fetch_nebius.py +335 -0
  34. sky/catalog/data_fetchers/fetch_runpod.py +698 -0
  35. sky/catalog/data_fetchers/fetch_seeweb.py +329 -0
  36. sky/catalog/data_fetchers/fetch_shadeform.py +142 -0
  37. sky/{clouds/service_catalog → catalog}/data_fetchers/fetch_vast.py +1 -1
  38. sky/{clouds/service_catalog → catalog}/data_fetchers/fetch_vsphere.py +1 -1
  39. sky/{clouds/service_catalog → catalog}/do_catalog.py +5 -2
  40. sky/{clouds/service_catalog → catalog}/fluidstack_catalog.py +6 -3
  41. sky/{clouds/service_catalog → catalog}/gcp_catalog.py +41 -15
  42. sky/catalog/hyperbolic_catalog.py +136 -0
  43. sky/{clouds/service_catalog → catalog}/ibm_catalog.py +9 -6
  44. sky/{clouds/service_catalog → catalog}/kubernetes_catalog.py +36 -24
  45. sky/{clouds/service_catalog → catalog}/lambda_catalog.py +9 -6
  46. sky/{clouds/service_catalog → catalog}/nebius_catalog.py +9 -7
  47. sky/{clouds/service_catalog → catalog}/oci_catalog.py +9 -6
  48. sky/{clouds/service_catalog → catalog}/paperspace_catalog.py +5 -2
  49. sky/catalog/primeintellect_catalog.py +95 -0
  50. sky/{clouds/service_catalog → catalog}/runpod_catalog.py +11 -4
  51. sky/{clouds/service_catalog → catalog}/scp_catalog.py +9 -6
  52. sky/catalog/seeweb_catalog.py +184 -0
  53. sky/catalog/shadeform_catalog.py +165 -0
  54. sky/catalog/ssh_catalog.py +167 -0
  55. sky/{clouds/service_catalog → catalog}/vast_catalog.py +6 -3
  56. sky/{clouds/service_catalog → catalog}/vsphere_catalog.py +5 -2
  57. sky/check.py +491 -203
  58. sky/cli.py +5 -6005
  59. sky/client/{cli.py → cli/command.py} +2477 -1885
  60. sky/client/cli/deprecation_utils.py +99 -0
  61. sky/client/cli/flags.py +359 -0
  62. sky/client/cli/table_utils.py +320 -0
  63. sky/client/common.py +70 -32
  64. sky/client/oauth.py +82 -0
  65. sky/client/sdk.py +1203 -297
  66. sky/client/sdk_async.py +833 -0
  67. sky/client/service_account_auth.py +47 -0
  68. sky/cloud_stores.py +73 -0
  69. sky/clouds/__init__.py +13 -0
  70. sky/clouds/aws.py +358 -93
  71. sky/clouds/azure.py +105 -83
  72. sky/clouds/cloud.py +127 -36
  73. sky/clouds/cudo.py +68 -50
  74. sky/clouds/do.py +66 -48
  75. sky/clouds/fluidstack.py +63 -44
  76. sky/clouds/gcp.py +339 -110
  77. sky/clouds/hyperbolic.py +293 -0
  78. sky/clouds/ibm.py +70 -49
  79. sky/clouds/kubernetes.py +563 -162
  80. sky/clouds/lambda_cloud.py +74 -54
  81. sky/clouds/nebius.py +206 -80
  82. sky/clouds/oci.py +88 -66
  83. sky/clouds/paperspace.py +61 -44
  84. sky/clouds/primeintellect.py +317 -0
  85. sky/clouds/runpod.py +164 -74
  86. sky/clouds/scp.py +89 -83
  87. sky/clouds/seeweb.py +466 -0
  88. sky/clouds/shadeform.py +400 -0
  89. sky/clouds/ssh.py +263 -0
  90. sky/clouds/utils/aws_utils.py +10 -4
  91. sky/clouds/utils/gcp_utils.py +87 -11
  92. sky/clouds/utils/oci_utils.py +38 -14
  93. sky/clouds/utils/scp_utils.py +177 -124
  94. sky/clouds/vast.py +99 -77
  95. sky/clouds/vsphere.py +51 -40
  96. sky/core.py +349 -139
  97. sky/dag.py +15 -0
  98. sky/dashboard/out/404.html +1 -1
  99. sky/dashboard/out/_next/static/chunks/1141-e6aa9ab418717c59.js +11 -0
  100. sky/dashboard/out/_next/static/chunks/1272-1ef0bf0237faccdb.js +1 -0
  101. sky/dashboard/out/_next/static/chunks/1871-74503c8e80fd253b.js +6 -0
  102. sky/dashboard/out/_next/static/chunks/2260-7703229c33c5ebd5.js +1 -0
  103. sky/dashboard/out/_next/static/chunks/2350.fab69e61bac57b23.js +1 -0
  104. sky/dashboard/out/_next/static/chunks/2369.fc20f0c2c8ed9fe7.js +15 -0
  105. sky/dashboard/out/_next/static/chunks/2755.fff53c4a3fcae910.js +26 -0
  106. sky/dashboard/out/_next/static/chunks/3294.72362fa129305b19.js +1 -0
  107. sky/dashboard/out/_next/static/chunks/3785.ad6adaa2a0fa9768.js +1 -0
  108. sky/dashboard/out/_next/static/chunks/3850-ff4a9a69d978632b.js +1 -0
  109. sky/dashboard/out/_next/static/chunks/3937.210053269f121201.js +1 -0
  110. sky/dashboard/out/_next/static/chunks/4725.a830b5c9e7867c92.js +1 -0
  111. sky/dashboard/out/_next/static/chunks/4937.a2baa2df5572a276.js +15 -0
  112. sky/dashboard/out/_next/static/chunks/5739-d67458fcb1386c92.js +8 -0
  113. sky/dashboard/out/_next/static/chunks/6130-2be46d70a38f1e82.js +1 -0
  114. sky/dashboard/out/_next/static/chunks/616-3d59f75e2ccf9321.js +39 -0
  115. sky/dashboard/out/_next/static/chunks/6212-7bd06f60ba693125.js +13 -0
  116. sky/dashboard/out/_next/static/chunks/6601-06114c982db410b6.js +1 -0
  117. sky/dashboard/out/_next/static/chunks/6856-ef8ba11f96d8c4a3.js +1 -0
  118. sky/dashboard/out/_next/static/chunks/6989-01359c57e018caa4.js +1 -0
  119. sky/dashboard/out/_next/static/chunks/6990-32b6e2d3822301fa.js +1 -0
  120. sky/dashboard/out/_next/static/chunks/7359-c8d04e06886000b3.js +30 -0
  121. sky/dashboard/out/_next/static/chunks/7411-b15471acd2cba716.js +41 -0
  122. sky/dashboard/out/_next/static/chunks/7615-3301e838e5f25772.js +1 -0
  123. sky/dashboard/out/_next/static/chunks/8640.5b9475a2d18c5416.js +16 -0
  124. sky/dashboard/out/_next/static/chunks/8969-1e4613c651bf4051.js +1 -0
  125. sky/dashboard/out/_next/static/chunks/9025.fa408f3242e9028d.js +6 -0
  126. sky/dashboard/out/_next/static/chunks/9353-cff34f7e773b2e2b.js +1 -0
  127. sky/dashboard/out/_next/static/chunks/9360.7310982cf5a0dc79.js +31 -0
  128. sky/dashboard/out/_next/static/chunks/9847.3aaca6bb33455140.js +30 -0
  129. sky/dashboard/out/_next/static/chunks/fd9d1056-86323a29a8f7e46a.js +1 -0
  130. sky/dashboard/out/_next/static/chunks/framework-cf60a09ccd051a10.js +33 -0
  131. sky/dashboard/out/_next/static/chunks/main-app-587214043926b3cc.js +1 -0
  132. sky/dashboard/out/_next/static/chunks/main-f15ccb73239a3bf1.js +1 -0
  133. sky/dashboard/out/_next/static/chunks/pages/_app-bde01e4a2beec258.js +34 -0
  134. sky/dashboard/out/_next/static/chunks/pages/_error-c66a4e8afc46f17b.js +1 -0
  135. sky/dashboard/out/_next/static/chunks/pages/clusters/[cluster]/[job]-c736ead69c2d86ec.js +16 -0
  136. sky/dashboard/out/_next/static/chunks/pages/clusters/[cluster]-a37d2063af475a1c.js +1 -0
  137. sky/dashboard/out/_next/static/chunks/pages/clusters-d44859594e6f8064.js +1 -0
  138. sky/dashboard/out/_next/static/chunks/pages/config-dfb9bf07b13045f4.js +1 -0
  139. sky/dashboard/out/_next/static/chunks/pages/index-444f1804401f04ea.js +1 -0
  140. sky/dashboard/out/_next/static/chunks/pages/infra/[context]-c0b5935149902e6f.js +1 -0
  141. sky/dashboard/out/_next/static/chunks/pages/infra-aed0ea19df7cf961.js +1 -0
  142. sky/dashboard/out/_next/static/chunks/pages/jobs/[job]-5796e8d6aea291a0.js +16 -0
  143. sky/dashboard/out/_next/static/chunks/pages/jobs/pools/[pool]-6edeb7d06032adfc.js +21 -0
  144. sky/dashboard/out/_next/static/chunks/pages/jobs-479dde13399cf270.js +1 -0
  145. sky/dashboard/out/_next/static/chunks/pages/users-5ab3b907622cf0fe.js +1 -0
  146. sky/dashboard/out/_next/static/chunks/pages/volumes-b84b948ff357c43e.js +1 -0
  147. sky/dashboard/out/_next/static/chunks/pages/workspace/new-3f88a1c7e86a3f86.js +1 -0
  148. sky/dashboard/out/_next/static/chunks/pages/workspaces/[name]-c5a3eeee1c218af1.js +1 -0
  149. sky/dashboard/out/_next/static/chunks/pages/workspaces-22b23febb3e89ce1.js +1 -0
  150. sky/dashboard/out/_next/static/chunks/webpack-2679be77fc08a2f8.js +1 -0
  151. sky/dashboard/out/_next/static/css/0748ce22df867032.css +3 -0
  152. sky/dashboard/out/_next/static/zB0ed6ge_W1MDszVHhijS/_buildManifest.js +1 -0
  153. sky/dashboard/out/clusters/[cluster]/[job].html +1 -1
  154. sky/dashboard/out/clusters/[cluster].html +1 -1
  155. sky/dashboard/out/clusters.html +1 -1
  156. sky/dashboard/out/config.html +1 -0
  157. sky/dashboard/out/index.html +1 -1
  158. sky/dashboard/out/infra/[context].html +1 -0
  159. sky/dashboard/out/infra.html +1 -0
  160. sky/dashboard/out/jobs/[job].html +1 -1
  161. sky/dashboard/out/jobs/pools/[pool].html +1 -0
  162. sky/dashboard/out/jobs.html +1 -1
  163. sky/dashboard/out/users.html +1 -0
  164. sky/dashboard/out/volumes.html +1 -0
  165. sky/dashboard/out/workspace/new.html +1 -0
  166. sky/dashboard/out/workspaces/[name].html +1 -0
  167. sky/dashboard/out/workspaces.html +1 -0
  168. sky/data/data_utils.py +137 -1
  169. sky/data/mounting_utils.py +269 -84
  170. sky/data/storage.py +1451 -1807
  171. sky/data/storage_utils.py +43 -57
  172. sky/exceptions.py +132 -2
  173. sky/execution.py +206 -63
  174. sky/global_user_state.py +2374 -586
  175. sky/jobs/__init__.py +5 -0
  176. sky/jobs/client/sdk.py +242 -65
  177. sky/jobs/client/sdk_async.py +143 -0
  178. sky/jobs/constants.py +9 -8
  179. sky/jobs/controller.py +839 -277
  180. sky/jobs/file_content_utils.py +80 -0
  181. sky/jobs/log_gc.py +201 -0
  182. sky/jobs/recovery_strategy.py +398 -152
  183. sky/jobs/scheduler.py +315 -189
  184. sky/jobs/server/core.py +829 -255
  185. sky/jobs/server/server.py +156 -115
  186. sky/jobs/server/utils.py +136 -0
  187. sky/jobs/state.py +2092 -701
  188. sky/jobs/utils.py +1242 -160
  189. sky/logs/__init__.py +21 -0
  190. sky/logs/agent.py +108 -0
  191. sky/logs/aws.py +243 -0
  192. sky/logs/gcp.py +91 -0
  193. sky/metrics/__init__.py +0 -0
  194. sky/metrics/utils.py +443 -0
  195. sky/models.py +78 -1
  196. sky/optimizer.py +164 -70
  197. sky/provision/__init__.py +90 -4
  198. sky/provision/aws/config.py +147 -26
  199. sky/provision/aws/instance.py +135 -50
  200. sky/provision/azure/instance.py +10 -5
  201. sky/provision/common.py +13 -1
  202. sky/provision/cudo/cudo_machine_type.py +1 -1
  203. sky/provision/cudo/cudo_utils.py +14 -8
  204. sky/provision/cudo/cudo_wrapper.py +72 -71
  205. sky/provision/cudo/instance.py +10 -6
  206. sky/provision/do/instance.py +10 -6
  207. sky/provision/do/utils.py +4 -3
  208. sky/provision/docker_utils.py +114 -23
  209. sky/provision/fluidstack/instance.py +13 -8
  210. sky/provision/gcp/__init__.py +1 -0
  211. sky/provision/gcp/config.py +301 -19
  212. sky/provision/gcp/constants.py +218 -0
  213. sky/provision/gcp/instance.py +36 -8
  214. sky/provision/gcp/instance_utils.py +18 -4
  215. sky/provision/gcp/volume_utils.py +247 -0
  216. sky/provision/hyperbolic/__init__.py +12 -0
  217. sky/provision/hyperbolic/config.py +10 -0
  218. sky/provision/hyperbolic/instance.py +437 -0
  219. sky/provision/hyperbolic/utils.py +373 -0
  220. sky/provision/instance_setup.py +93 -14
  221. sky/provision/kubernetes/__init__.py +5 -0
  222. sky/provision/kubernetes/config.py +9 -52
  223. sky/provision/kubernetes/constants.py +17 -0
  224. sky/provision/kubernetes/instance.py +789 -247
  225. sky/provision/kubernetes/manifests/fusermount-server-daemonset.yaml +1 -2
  226. sky/provision/kubernetes/network.py +27 -17
  227. sky/provision/kubernetes/network_utils.py +40 -43
  228. sky/provision/kubernetes/utils.py +1192 -531
  229. sky/provision/kubernetes/volume.py +282 -0
  230. sky/provision/lambda_cloud/instance.py +22 -16
  231. sky/provision/nebius/constants.py +50 -0
  232. sky/provision/nebius/instance.py +19 -6
  233. sky/provision/nebius/utils.py +196 -91
  234. sky/provision/oci/instance.py +10 -5
  235. sky/provision/paperspace/instance.py +10 -7
  236. sky/provision/paperspace/utils.py +1 -1
  237. sky/provision/primeintellect/__init__.py +10 -0
  238. sky/provision/primeintellect/config.py +11 -0
  239. sky/provision/primeintellect/instance.py +454 -0
  240. sky/provision/primeintellect/utils.py +398 -0
  241. sky/provision/provisioner.py +110 -36
  242. sky/provision/runpod/__init__.py +5 -0
  243. sky/provision/runpod/instance.py +27 -6
  244. sky/provision/runpod/utils.py +51 -18
  245. sky/provision/runpod/volume.py +180 -0
  246. sky/provision/scp/__init__.py +15 -0
  247. sky/provision/scp/config.py +93 -0
  248. sky/provision/scp/instance.py +531 -0
  249. sky/provision/seeweb/__init__.py +11 -0
  250. sky/provision/seeweb/config.py +13 -0
  251. sky/provision/seeweb/instance.py +807 -0
  252. sky/provision/shadeform/__init__.py +11 -0
  253. sky/provision/shadeform/config.py +12 -0
  254. sky/provision/shadeform/instance.py +351 -0
  255. sky/provision/shadeform/shadeform_utils.py +83 -0
  256. sky/provision/ssh/__init__.py +18 -0
  257. sky/provision/vast/instance.py +13 -8
  258. sky/provision/vast/utils.py +10 -7
  259. sky/provision/vsphere/common/vim_utils.py +1 -2
  260. sky/provision/vsphere/instance.py +15 -10
  261. sky/provision/vsphere/vsphere_utils.py +9 -19
  262. sky/py.typed +0 -0
  263. sky/resources.py +844 -118
  264. sky/schemas/__init__.py +0 -0
  265. sky/schemas/api/__init__.py +0 -0
  266. sky/schemas/api/responses.py +225 -0
  267. sky/schemas/db/README +4 -0
  268. sky/schemas/db/env.py +90 -0
  269. sky/schemas/db/global_user_state/001_initial_schema.py +124 -0
  270. sky/schemas/db/global_user_state/002_add_workspace_to_cluster_history.py +35 -0
  271. sky/schemas/db/global_user_state/003_fix_initial_revision.py +61 -0
  272. sky/schemas/db/global_user_state/004_is_managed.py +34 -0
  273. sky/schemas/db/global_user_state/005_cluster_event.py +32 -0
  274. sky/schemas/db/global_user_state/006_provision_log.py +41 -0
  275. sky/schemas/db/global_user_state/007_cluster_event_request_id.py +34 -0
  276. sky/schemas/db/global_user_state/008_skylet_ssh_tunnel_metadata.py +34 -0
  277. sky/schemas/db/global_user_state/009_last_activity_and_launched_at.py +89 -0
  278. sky/schemas/db/global_user_state/010_save_ssh_key.py +66 -0
  279. sky/schemas/db/script.py.mako +28 -0
  280. sky/schemas/db/serve_state/001_initial_schema.py +67 -0
  281. sky/schemas/db/skypilot_config/001_initial_schema.py +30 -0
  282. sky/schemas/db/spot_jobs/001_initial_schema.py +97 -0
  283. sky/schemas/db/spot_jobs/002_cluster_pool.py +42 -0
  284. sky/schemas/db/spot_jobs/003_pool_hash.py +34 -0
  285. sky/schemas/db/spot_jobs/004_job_file_contents.py +42 -0
  286. sky/schemas/db/spot_jobs/005_logs_gc.py +38 -0
  287. sky/schemas/generated/__init__.py +0 -0
  288. sky/schemas/generated/autostopv1_pb2.py +36 -0
  289. sky/schemas/generated/autostopv1_pb2.pyi +43 -0
  290. sky/schemas/generated/autostopv1_pb2_grpc.py +146 -0
  291. sky/schemas/generated/jobsv1_pb2.py +86 -0
  292. sky/schemas/generated/jobsv1_pb2.pyi +254 -0
  293. sky/schemas/generated/jobsv1_pb2_grpc.py +542 -0
  294. sky/schemas/generated/managed_jobsv1_pb2.py +74 -0
  295. sky/schemas/generated/managed_jobsv1_pb2.pyi +278 -0
  296. sky/schemas/generated/managed_jobsv1_pb2_grpc.py +278 -0
  297. sky/schemas/generated/servev1_pb2.py +58 -0
  298. sky/schemas/generated/servev1_pb2.pyi +115 -0
  299. sky/schemas/generated/servev1_pb2_grpc.py +322 -0
  300. sky/serve/autoscalers.py +357 -5
  301. sky/serve/client/impl.py +310 -0
  302. sky/serve/client/sdk.py +47 -139
  303. sky/serve/client/sdk_async.py +130 -0
  304. sky/serve/constants.py +10 -8
  305. sky/serve/controller.py +64 -19
  306. sky/serve/load_balancer.py +106 -60
  307. sky/serve/load_balancing_policies.py +115 -1
  308. sky/serve/replica_managers.py +273 -162
  309. sky/serve/serve_rpc_utils.py +179 -0
  310. sky/serve/serve_state.py +554 -251
  311. sky/serve/serve_utils.py +733 -220
  312. sky/serve/server/core.py +66 -711
  313. sky/serve/server/impl.py +1093 -0
  314. sky/serve/server/server.py +21 -18
  315. sky/serve/service.py +133 -48
  316. sky/serve/service_spec.py +135 -16
  317. sky/serve/spot_placer.py +3 -0
  318. sky/server/auth/__init__.py +0 -0
  319. sky/server/auth/authn.py +50 -0
  320. sky/server/auth/loopback.py +38 -0
  321. sky/server/auth/oauth2_proxy.py +200 -0
  322. sky/server/common.py +475 -181
  323. sky/server/config.py +81 -23
  324. sky/server/constants.py +44 -6
  325. sky/server/daemons.py +229 -0
  326. sky/server/html/token_page.html +185 -0
  327. sky/server/metrics.py +160 -0
  328. sky/server/requests/executor.py +528 -138
  329. sky/server/requests/payloads.py +351 -17
  330. sky/server/requests/preconditions.py +21 -17
  331. sky/server/requests/process.py +112 -29
  332. sky/server/requests/request_names.py +120 -0
  333. sky/server/requests/requests.py +817 -224
  334. sky/server/requests/serializers/decoders.py +82 -31
  335. sky/server/requests/serializers/encoders.py +140 -22
  336. sky/server/requests/threads.py +106 -0
  337. sky/server/rest.py +417 -0
  338. sky/server/server.py +1290 -284
  339. sky/server/state.py +20 -0
  340. sky/server/stream_utils.py +345 -57
  341. sky/server/uvicorn.py +217 -3
  342. sky/server/versions.py +270 -0
  343. sky/setup_files/MANIFEST.in +5 -0
  344. sky/setup_files/alembic.ini +156 -0
  345. sky/setup_files/dependencies.py +136 -31
  346. sky/setup_files/setup.py +44 -42
  347. sky/sky_logging.py +102 -5
  348. sky/skylet/attempt_skylet.py +1 -0
  349. sky/skylet/autostop_lib.py +129 -8
  350. sky/skylet/configs.py +27 -20
  351. sky/skylet/constants.py +171 -19
  352. sky/skylet/events.py +105 -21
  353. sky/skylet/job_lib.py +335 -104
  354. sky/skylet/log_lib.py +297 -18
  355. sky/skylet/log_lib.pyi +44 -1
  356. sky/skylet/ray_patches/__init__.py +17 -3
  357. sky/skylet/ray_patches/autoscaler.py.diff +18 -0
  358. sky/skylet/ray_patches/cli.py.diff +19 -0
  359. sky/skylet/ray_patches/command_runner.py.diff +17 -0
  360. sky/skylet/ray_patches/log_monitor.py.diff +20 -0
  361. sky/skylet/ray_patches/resource_demand_scheduler.py.diff +32 -0
  362. sky/skylet/ray_patches/updater.py.diff +18 -0
  363. sky/skylet/ray_patches/worker.py.diff +41 -0
  364. sky/skylet/services.py +564 -0
  365. sky/skylet/skylet.py +63 -4
  366. sky/skylet/subprocess_daemon.py +103 -29
  367. sky/skypilot_config.py +506 -99
  368. sky/ssh_node_pools/__init__.py +1 -0
  369. sky/ssh_node_pools/core.py +135 -0
  370. sky/ssh_node_pools/server.py +233 -0
  371. sky/task.py +621 -137
  372. sky/templates/aws-ray.yml.j2 +10 -3
  373. sky/templates/azure-ray.yml.j2 +1 -1
  374. sky/templates/do-ray.yml.j2 +1 -1
  375. sky/templates/gcp-ray.yml.j2 +57 -0
  376. sky/templates/hyperbolic-ray.yml.j2 +67 -0
  377. sky/templates/jobs-controller.yaml.j2 +27 -24
  378. sky/templates/kubernetes-loadbalancer.yml.j2 +2 -0
  379. sky/templates/kubernetes-ray.yml.j2 +607 -51
  380. sky/templates/lambda-ray.yml.j2 +1 -1
  381. sky/templates/nebius-ray.yml.j2 +33 -12
  382. sky/templates/paperspace-ray.yml.j2 +1 -1
  383. sky/templates/primeintellect-ray.yml.j2 +71 -0
  384. sky/templates/runpod-ray.yml.j2 +9 -1
  385. sky/templates/scp-ray.yml.j2 +3 -50
  386. sky/templates/seeweb-ray.yml.j2 +108 -0
  387. sky/templates/shadeform-ray.yml.j2 +72 -0
  388. sky/templates/sky-serve-controller.yaml.j2 +22 -2
  389. sky/templates/websocket_proxy.py +178 -18
  390. sky/usage/usage_lib.py +18 -11
  391. sky/users/__init__.py +0 -0
  392. sky/users/model.conf +15 -0
  393. sky/users/permission.py +387 -0
  394. sky/users/rbac.py +121 -0
  395. sky/users/server.py +720 -0
  396. sky/users/token_service.py +218 -0
  397. sky/utils/accelerator_registry.py +34 -5
  398. sky/utils/admin_policy_utils.py +84 -38
  399. sky/utils/annotations.py +16 -5
  400. sky/utils/asyncio_utils.py +78 -0
  401. sky/utils/auth_utils.py +153 -0
  402. sky/utils/benchmark_utils.py +60 -0
  403. sky/utils/cli_utils/status_utils.py +159 -86
  404. sky/utils/cluster_utils.py +31 -9
  405. sky/utils/command_runner.py +354 -68
  406. sky/utils/command_runner.pyi +93 -3
  407. sky/utils/common.py +35 -8
  408. sky/utils/common_utils.py +310 -87
  409. sky/utils/config_utils.py +87 -5
  410. sky/utils/context.py +402 -0
  411. sky/utils/context_utils.py +222 -0
  412. sky/utils/controller_utils.py +264 -89
  413. sky/utils/dag_utils.py +31 -12
  414. sky/utils/db/__init__.py +0 -0
  415. sky/utils/db/db_utils.py +470 -0
  416. sky/utils/db/migration_utils.py +133 -0
  417. sky/utils/directory_utils.py +12 -0
  418. sky/utils/env_options.py +13 -0
  419. sky/utils/git.py +567 -0
  420. sky/utils/git_clone.sh +460 -0
  421. sky/utils/infra_utils.py +195 -0
  422. sky/utils/kubernetes/cleanup-tunnel.sh +62 -0
  423. sky/utils/kubernetes/config_map_utils.py +133 -0
  424. sky/utils/kubernetes/create_cluster.sh +13 -27
  425. sky/utils/kubernetes/delete_cluster.sh +10 -7
  426. sky/utils/kubernetes/deploy_remote_cluster.py +1299 -0
  427. sky/utils/kubernetes/exec_kubeconfig_converter.py +22 -31
  428. sky/utils/kubernetes/generate_kind_config.py +6 -66
  429. sky/utils/kubernetes/generate_kubeconfig.sh +4 -1
  430. sky/utils/kubernetes/gpu_labeler.py +5 -5
  431. sky/utils/kubernetes/kubernetes_deploy_utils.py +354 -47
  432. sky/utils/kubernetes/ssh-tunnel.sh +379 -0
  433. sky/utils/kubernetes/ssh_utils.py +221 -0
  434. sky/utils/kubernetes_enums.py +8 -15
  435. sky/utils/lock_events.py +94 -0
  436. sky/utils/locks.py +368 -0
  437. sky/utils/log_utils.py +300 -6
  438. sky/utils/perf_utils.py +22 -0
  439. sky/utils/resource_checker.py +298 -0
  440. sky/utils/resources_utils.py +249 -32
  441. sky/utils/rich_utils.py +213 -37
  442. sky/utils/schemas.py +905 -147
  443. sky/utils/serialize_utils.py +16 -0
  444. sky/utils/status_lib.py +10 -0
  445. sky/utils/subprocess_utils.py +38 -15
  446. sky/utils/tempstore.py +70 -0
  447. sky/utils/timeline.py +24 -52
  448. sky/utils/ux_utils.py +84 -15
  449. sky/utils/validator.py +11 -1
  450. sky/utils/volume.py +86 -0
  451. sky/utils/yaml_utils.py +111 -0
  452. sky/volumes/__init__.py +13 -0
  453. sky/volumes/client/__init__.py +0 -0
  454. sky/volumes/client/sdk.py +149 -0
  455. sky/volumes/server/__init__.py +0 -0
  456. sky/volumes/server/core.py +258 -0
  457. sky/volumes/server/server.py +122 -0
  458. sky/volumes/volume.py +212 -0
  459. sky/workspaces/__init__.py +0 -0
  460. sky/workspaces/core.py +655 -0
  461. sky/workspaces/server.py +101 -0
  462. sky/workspaces/utils.py +56 -0
  463. skypilot_nightly-1.0.0.dev20251107.dist-info/METADATA +675 -0
  464. skypilot_nightly-1.0.0.dev20251107.dist-info/RECORD +594 -0
  465. {skypilot_nightly-1.0.0.dev20250509.dist-info → skypilot_nightly-1.0.0.dev20251107.dist-info}/WHEEL +1 -1
  466. sky/benchmark/benchmark_state.py +0 -256
  467. sky/benchmark/benchmark_utils.py +0 -641
  468. sky/clouds/service_catalog/constants.py +0 -7
  469. sky/dashboard/out/_next/static/LksQgChY5izXjokL3LcEu/_buildManifest.js +0 -1
  470. sky/dashboard/out/_next/static/chunks/236-f49500b82ad5392d.js +0 -6
  471. sky/dashboard/out/_next/static/chunks/312-c3c8845990db8ffc.js +0 -15
  472. sky/dashboard/out/_next/static/chunks/37-0a572fe0dbb89c4d.js +0 -6
  473. sky/dashboard/out/_next/static/chunks/678-206dddca808e6d16.js +0 -59
  474. sky/dashboard/out/_next/static/chunks/845-0f8017370869e269.js +0 -1
  475. sky/dashboard/out/_next/static/chunks/979-7bf73a4c7cea0f5c.js +0 -1
  476. sky/dashboard/out/_next/static/chunks/fd9d1056-2821b0f0cabcd8bd.js +0 -1
  477. sky/dashboard/out/_next/static/chunks/framework-87d061ee6ed71b28.js +0 -33
  478. sky/dashboard/out/_next/static/chunks/main-app-241eb28595532291.js +0 -1
  479. sky/dashboard/out/_next/static/chunks/main-e0e2335212e72357.js +0 -1
  480. sky/dashboard/out/_next/static/chunks/pages/_app-e6b013bc3f77ad60.js +0 -1
  481. sky/dashboard/out/_next/static/chunks/pages/_error-1be831200e60c5c0.js +0 -1
  482. sky/dashboard/out/_next/static/chunks/pages/clusters/[cluster]/[job]-e15db85d0ea1fbe1.js +0 -1
  483. sky/dashboard/out/_next/static/chunks/pages/clusters/[cluster]-f383db7389368ea7.js +0 -1
  484. sky/dashboard/out/_next/static/chunks/pages/clusters-a93b93e10b8b074e.js +0 -1
  485. sky/dashboard/out/_next/static/chunks/pages/index-f9f039532ca8cbc4.js +0 -1
  486. sky/dashboard/out/_next/static/chunks/pages/jobs/[job]-03f279c6741fb48b.js +0 -1
  487. sky/dashboard/out/_next/static/chunks/pages/jobs-a75029b67aab6a2e.js +0 -1
  488. sky/dashboard/out/_next/static/chunks/webpack-830f59b8404e96b8.js +0 -1
  489. sky/dashboard/out/_next/static/css/c6933bbb2ce7f4dd.css +0 -3
  490. sky/jobs/dashboard/dashboard.py +0 -223
  491. sky/jobs/dashboard/static/favicon.ico +0 -0
  492. sky/jobs/dashboard/templates/index.html +0 -831
  493. sky/jobs/server/dashboard_utils.py +0 -69
  494. sky/skylet/providers/scp/__init__.py +0 -2
  495. sky/skylet/providers/scp/config.py +0 -149
  496. sky/skylet/providers/scp/node_provider.py +0 -578
  497. sky/templates/kubernetes-ssh-jump.yml.j2 +0 -94
  498. sky/utils/db_utils.py +0 -100
  499. sky/utils/kubernetes/deploy_remote_cluster.sh +0 -308
  500. sky/utils/kubernetes/ssh_jump_lifecycle_manager.py +0 -191
  501. skypilot_nightly-1.0.0.dev20250509.dist-info/METADATA +0 -361
  502. skypilot_nightly-1.0.0.dev20250509.dist-info/RECORD +0 -396
  503. /sky/{clouds/service_catalog → catalog}/config.py +0 -0
  504. /sky/{benchmark → catalog/data_fetchers}/__init__.py +0 -0
  505. /sky/{clouds/service_catalog → catalog}/data_fetchers/fetch_azure.py +0 -0
  506. /sky/{clouds/service_catalog → catalog}/data_fetchers/fetch_fluidstack.py +0 -0
  507. /sky/{clouds/service_catalog → catalog}/data_fetchers/fetch_ibm.py +0 -0
  508. /sky/{clouds/service_catalog/data_fetchers → client/cli}/__init__.py +0 -0
  509. /sky/dashboard/out/_next/static/{LksQgChY5izXjokL3LcEu → zB0ed6ge_W1MDszVHhijS}/_ssgManifest.js +0 -0
  510. {skypilot_nightly-1.0.0.dev20250509.dist-info → skypilot_nightly-1.0.0.dev20251107.dist-info}/entry_points.txt +0 -0
  511. {skypilot_nightly-1.0.0.dev20250509.dist-info → skypilot_nightly-1.0.0.dev20251107.dist-info}/licenses/LICENSE +0 -0
  512. {skypilot_nightly-1.0.0.dev20250509.dist-info → skypilot_nightly-1.0.0.dev20251107.dist-info}/top_level.txt +0 -0
sky/utils/schemas.py CHANGED
@@ -6,7 +6,9 @@ https://json-schema.org/
6
6
  import enum
7
7
  from typing import Any, Dict, List, Tuple
8
8
 
9
+ from sky.skylet import autostop_lib
9
10
  from sky.skylet import constants
11
+ from sky.utils import kubernetes_enums
10
12
 
11
13
 
12
14
  def _check_not_both_fields_present(field1: str, field2: str):
@@ -33,11 +35,114 @@ def _check_not_both_fields_present(field1: str, field2: str):
33
35
  }
34
36
 
35
37
 
38
+ _AUTOSTOP_SCHEMA = {
39
+ 'anyOf': [
40
+ {
41
+ # Use boolean to disable autostop completely, e.g.
42
+ # autostop: false
43
+ 'type': 'boolean',
44
+ },
45
+ {
46
+ # Shorthand to set idle_minutes by directly specifying, e.g.
47
+ # autostop: 5
48
+ 'anyOf': [{
49
+ 'type': 'string',
50
+ 'pattern': constants.TIME_PATTERN,
51
+ 'minimum': 0,
52
+ }, {
53
+ 'type': 'integer',
54
+ }]
55
+ },
56
+ {
57
+ 'type': 'object',
58
+ 'required': [],
59
+ 'additionalProperties': False,
60
+ 'properties': {
61
+ # TODO(luca): update field to use time units as well.
62
+ 'idle_minutes': {
63
+ 'type': 'integer',
64
+ 'minimum': 0,
65
+ },
66
+ 'down': {
67
+ 'type': 'boolean',
68
+ },
69
+ 'wait_for': {
70
+ 'type': 'string',
71
+ 'case_insensitive_enum':
72
+ autostop_lib.AutostopWaitFor.supported_modes(),
73
+ }
74
+ },
75
+ },
76
+ ],
77
+ }
78
+
79
+
80
+ # Note: This is similar to _get_infra_pattern()
81
+ # but without the wildcard patterns.
82
+ def _get_volume_infra_pattern():
83
+ # Building the regex pattern for the infra field
84
+ # Format: cloud[/region[/zone]] or wildcards or kubernetes context
85
+ # Match any cloud name (case insensitive)
86
+ all_clouds = list(constants.ALL_CLOUDS)
87
+ all_clouds.remove('kubernetes')
88
+ cloud_pattern = f'(?i:({"|".join(all_clouds)}))'
89
+
90
+ # Optional /region followed by optional /zone
91
+ # /[^/]+ matches a slash followed by any characters except slash (region or
92
+ # zone name)
93
+ # The outer (?:...)? makes the entire region/zone part optional
94
+ region_zone_pattern = '(?:/[^/]+(?:/[^/]+)?)?'
95
+
96
+ # Kubernetes specific pattern - matches:
97
+ # 1. Just the word "kubernetes" or "k8s" by itself
98
+ # 2. "k8s/" or "kubernetes/" followed by any context name (which may contain
99
+ # slashes)
100
+ kubernetes_pattern = '(?i:kubernetes|k8s)(?:/.+)?'
101
+
102
+ # Combine all patterns with alternation (|)
103
+ # ^ marks start of string, $ marks end of string
104
+ infra_pattern = (f'^(?:{cloud_pattern}{region_zone_pattern}|'
105
+ f'{kubernetes_pattern})$')
106
+ return infra_pattern
107
+
108
+
109
+ def _get_infra_pattern():
110
+ # Building the regex pattern for the infra field
111
+ # Format: cloud[/region[/zone]] or wildcards or kubernetes context
112
+ # Match any cloud name (case insensitive)
113
+ all_clouds = list(constants.ALL_CLOUDS)
114
+ all_clouds.remove('kubernetes')
115
+ cloud_pattern = f'(?i:({"|".join(all_clouds)}))'
116
+
117
+ # Optional /region followed by optional /zone
118
+ # /[^/]+ matches a slash followed by any characters except slash (region or
119
+ # zone name)
120
+ # The outer (?:...)? makes the entire region/zone part optional
121
+ region_zone_pattern = '(?:/[^/]+(?:/[^/]+)?)?'
122
+
123
+ # Wildcard patterns:
124
+ # 1. * - any cloud
125
+ # 2. */region - any cloud with specific region
126
+ # 3. */*/zone - any cloud, any region, specific zone
127
+ wildcard_cloud = '\\*' # Wildcard for cloud
128
+ wildcard_with_region = '(?:/[^/]+(?:/[^/]+)?)?'
129
+
130
+ # Kubernetes specific pattern - matches:
131
+ # 1. Just the word "kubernetes" or "k8s" by itself
132
+ # 2. "k8s/" or "kubernetes/" followed by any context name (which may contain
133
+ # slashes)
134
+ kubernetes_pattern = '(?i:kubernetes|k8s)(?:/.+)?'
135
+
136
+ # Combine all patterns with alternation (|)
137
+ # ^ marks start of string, $ marks end of string
138
+ infra_pattern = (f'^(?:{cloud_pattern}{region_zone_pattern}|'
139
+ f'{wildcard_cloud}{wildcard_with_region}|'
140
+ f'{kubernetes_pattern})$')
141
+ return infra_pattern
142
+
143
+
36
144
  def _get_single_resources_schema():
37
145
  """Schema for a single resource in a resources list."""
38
- # To avoid circular imports, only import when needed.
39
- # pylint: disable=import-outside-toplevel
40
- from sky.clouds import service_catalog
41
146
  return {
42
147
  '$schema': 'https://json-schema.org/draft/2020-12/schema',
43
148
  'type': 'object',
@@ -46,7 +151,7 @@ def _get_single_resources_schema():
46
151
  'properties': {
47
152
  'cloud': {
48
153
  'type': 'string',
49
- 'case_insensitive_enum': list(service_catalog.ALL_CLOUDS)
154
+ 'case_insensitive_enum': list(constants.ALL_CLOUDS)
50
155
  },
51
156
  'region': {
52
157
  'type': 'string',
@@ -54,6 +159,21 @@ def _get_single_resources_schema():
54
159
  'zone': {
55
160
  'type': 'string',
56
161
  },
162
+ 'infra': {
163
+ 'type': 'string',
164
+ 'description':
165
+ ('Infrastructure specification in format: '
166
+ 'cloud[/region[/zone]]. Use "*" as a wildcard.'),
167
+ # Pattern validates:
168
+ # 1. cloud[/region[/zone]] - e.g. "aws", "aws/us-east-1",
169
+ # "aws/us-east-1/us-east-1a"
170
+ # 2. Wildcard patterns - e.g. "*", "*/us-east-1",
171
+ # "*/*/us-east-1a", "aws/*/us-east-1a"
172
+ # 3. Kubernetes patterns - e.g. "kubernetes/my-context",
173
+ # "k8s/context-name",
174
+ # "k8s/aws:eks:us-east-1:123456789012:cluster/my-cluster"
175
+ 'pattern': _get_infra_pattern(),
176
+ },
57
177
  'cpus': {
58
178
  'anyOf': [{
59
179
  'type': 'string',
@@ -109,12 +229,54 @@ def _get_single_resources_schema():
109
229
  }
110
230
  }],
111
231
  },
232
+ 'volumes': {
233
+ 'type': 'array',
234
+ 'items': {
235
+ 'type': 'object',
236
+ 'properties': {
237
+ 'disk_size': {
238
+ 'anyOf': [{
239
+ 'type': 'string',
240
+ 'pattern': constants.MEMORY_SIZE_PATTERN,
241
+ }, {
242
+ 'type': 'integer',
243
+ }],
244
+ },
245
+ 'disk_tier': {
246
+ 'type': 'string',
247
+ },
248
+ 'path': {
249
+ 'type': 'string',
250
+ },
251
+ 'auto_delete': {
252
+ 'type': 'boolean',
253
+ },
254
+ 'storage_type': {
255
+ 'type': 'string',
256
+ },
257
+ 'name': {
258
+ 'type': 'string',
259
+ },
260
+ 'attach_mode': {
261
+ 'type': 'string',
262
+ },
263
+ },
264
+ },
265
+ },
112
266
  'disk_size': {
113
- 'type': 'integer',
267
+ 'anyOf': [{
268
+ 'type': 'string',
269
+ 'pattern': constants.MEMORY_SIZE_PATTERN,
270
+ }, {
271
+ 'type': 'integer',
272
+ }],
114
273
  },
115
274
  'disk_tier': {
116
275
  'type': 'string',
117
276
  },
277
+ 'network_tier': {
278
+ 'type': 'string',
279
+ },
118
280
  'ports': {
119
281
  'anyOf': [{
120
282
  'type': 'string',
@@ -155,6 +317,9 @@ def _get_single_resources_schema():
155
317
  }
156
318
  }
157
319
  },
320
+ '_no_missing_accel_warnings': {
321
+ 'type': 'boolean'
322
+ },
158
323
  'image_id': {
159
324
  'anyOf': [{
160
325
  'type': 'string',
@@ -165,6 +330,12 @@ def _get_single_resources_schema():
165
330
  'type': 'null',
166
331
  }]
167
332
  },
333
+ 'autostop': _AUTOSTOP_SCHEMA,
334
+ 'priority': {
335
+ 'type': 'integer',
336
+ 'minimum': constants.MIN_PRIORITY,
337
+ 'maximum': constants.MAX_PRIORITY,
338
+ },
168
339
  # The following fields are for internal use only. Should not be
169
340
  # specified in the task config.
170
341
  '_docker_login_config': {
@@ -254,9 +425,71 @@ def get_resources_schema():
254
425
  }
255
426
 
256
427
 
428
+ def get_volume_schema():
429
+ # pylint: disable=import-outside-toplevel
430
+ from sky.utils import volume
431
+
432
+ return {
433
+ '$schema': 'https://json-schema.org/draft/2020-12/schema',
434
+ 'type': 'object',
435
+ 'required': ['name', 'type'],
436
+ 'additionalProperties': False,
437
+ 'properties': {
438
+ 'name': {
439
+ 'type': 'string',
440
+ },
441
+ 'type': {
442
+ 'type': 'string',
443
+ 'case_sensitive_enum': [
444
+ type.value for type in volume.VolumeType
445
+ ],
446
+ },
447
+ 'infra': {
448
+ 'type': 'string',
449
+ 'description': ('Infrastructure specification in format: '
450
+ 'cloud[/region[/zone]].'),
451
+ # Pattern validates:
452
+ # 1. cloud[/region[/zone]] - e.g. "aws", "aws/us-east-1",
453
+ # "aws/us-east-1/us-east-1a"
454
+ # 2. Kubernetes patterns - e.g. "kubernetes/my-context",
455
+ # "k8s/context-name",
456
+ # "k8s/aws:eks:us-east-1:123456789012:cluster/my-cluster"
457
+ 'pattern': _get_volume_infra_pattern(),
458
+ },
459
+ 'size': {
460
+ 'type': 'string',
461
+ 'pattern': constants.MEMORY_SIZE_PATTERN,
462
+ },
463
+ 'resource_name': {
464
+ 'type': 'string',
465
+ },
466
+ 'config': {
467
+ 'type': 'object',
468
+ 'required': [],
469
+ 'properties': {
470
+ 'storage_class_name': {
471
+ 'type': 'string',
472
+ },
473
+ 'access_mode': {
474
+ 'type': 'string',
475
+ 'case_sensitive_enum': [
476
+ type.value for type in volume.VolumeAccessMode
477
+ ],
478
+ },
479
+ 'namespace': {
480
+ 'type': 'string',
481
+ },
482
+ },
483
+ },
484
+ **_LABELS_SCHEMA,
485
+ }
486
+ }
487
+
488
+
257
489
  def get_storage_schema():
258
490
  # pylint: disable=import-outside-toplevel
259
491
  from sky.data import storage
492
+
260
493
  return {
261
494
  '$schema': 'https://json-schema.org/draft/2020-12/schema',
262
495
  'type': 'object',
@@ -292,6 +525,28 @@ def get_storage_schema():
292
525
  mode.value for mode in storage.StorageMode
293
526
  ]
294
527
  },
528
+ 'config': {
529
+ 'type': 'object',
530
+ 'properties': {
531
+ 'disk_size': {
532
+ 'anyOf': [{
533
+ 'type': 'string',
534
+ 'pattern': constants.MEMORY_SIZE_PATTERN,
535
+ }, {
536
+ 'type': 'integer',
537
+ }],
538
+ },
539
+ 'disk_tier': {
540
+ 'type': 'string',
541
+ },
542
+ 'storage_type': {
543
+ 'type': 'string',
544
+ },
545
+ 'attach_mode': {
546
+ 'type': 'string',
547
+ },
548
+ },
549
+ },
295
550
  '_is_sky_managed': {
296
551
  'type': 'boolean',
297
552
  },
@@ -305,6 +560,49 @@ def get_storage_schema():
305
560
  }
306
561
 
307
562
 
563
+ def get_volume_mount_schema():
564
+ """Schema for volume mount object in task config (internal use only)."""
565
+ return {
566
+ '$schema': 'https://json-schema.org/draft/2020-12/schema',
567
+ 'type': 'object',
568
+ 'required': [],
569
+ 'additionalProperties': False,
570
+ 'properties': {
571
+ 'path': {
572
+ 'type': 'string',
573
+ },
574
+ 'volume_name': {
575
+ 'type': 'string',
576
+ },
577
+ 'volume_config': {
578
+ 'type': 'object',
579
+ 'required': [],
580
+ 'additionalProperties': True,
581
+ 'properties': {
582
+ 'cloud': {
583
+ 'type': 'string',
584
+ 'case_insensitive_enum': list(constants.ALL_CLOUDS)
585
+ },
586
+ 'region': {
587
+ 'anyOf': [{
588
+ 'type': 'string'
589
+ }, {
590
+ 'type': 'null'
591
+ }]
592
+ },
593
+ 'zone': {
594
+ 'anyOf': [{
595
+ 'type': 'string'
596
+ }, {
597
+ 'type': 'null'
598
+ }]
599
+ },
600
+ },
601
+ }
602
+ }
603
+ }
604
+
605
+
308
606
  def get_service_schema():
309
607
  """Schema for top-level `service:` field (for SkyServe)."""
310
608
  # To avoid circular imports, only import when needed.
@@ -314,7 +612,6 @@ def get_service_schema():
314
612
  return {
315
613
  '$schema': 'https://json-schema.org/draft/2020-12/schema',
316
614
  'type': 'object',
317
- 'required': ['readiness_probe'],
318
615
  'additionalProperties': False,
319
616
  'properties': {
320
617
  'readiness_probe': {
@@ -350,6 +647,9 @@ def get_service_schema():
350
647
  }
351
648
  }]
352
649
  },
650
+ 'pool': {
651
+ 'type': 'boolean',
652
+ },
353
653
  'replica_policy': {
354
654
  'type': 'object',
355
655
  'required': ['min_replicas'],
@@ -368,8 +668,24 @@ def get_service_schema():
368
668
  'minimum': 0,
369
669
  },
370
670
  'target_qps_per_replica': {
371
- 'type': 'number',
372
- 'minimum': 0,
671
+ 'anyOf': [
672
+ {
673
+ 'type': 'number',
674
+ 'minimum': 0,
675
+ },
676
+ {
677
+ 'type': 'object',
678
+ 'patternProperties': {
679
+ # Pattern for accelerator types like
680
+ # "H100:1", "A100:1", "H100", "A100"
681
+ '^[A-Z0-9]+(?::[0-9]+)?$': {
682
+ 'type': 'number',
683
+ 'minimum': 0,
684
+ }
685
+ },
686
+ 'additionalProperties': False,
687
+ }
688
+ ]
373
689
  },
374
690
  'dynamic_ondemand_fallback': {
375
691
  'type': 'boolean',
@@ -397,6 +713,9 @@ def get_service_schema():
397
713
  'replicas': {
398
714
  'type': 'integer',
399
715
  },
716
+ 'workers': {
717
+ 'type': 'integer',
718
+ },
400
719
  'load_balancing_policy': {
401
720
  'type': 'string',
402
721
  'case_insensitive_enum': list(
@@ -500,7 +819,21 @@ def get_task_schema():
500
819
  'type': 'string',
501
820
  },
502
821
  'workdir': {
503
- 'type': 'string',
822
+ 'anyOf': [{
823
+ 'type': 'string',
824
+ }, {
825
+ 'type': 'object',
826
+ 'required': ['url'],
827
+ 'additionalProperties': False,
828
+ 'properties': {
829
+ 'url': {
830
+ 'type': 'string',
831
+ },
832
+ 'ref': {
833
+ 'type': 'string',
834
+ },
835
+ },
836
+ }],
504
837
  },
505
838
  'event_callback': {
506
839
  'type': 'string',
@@ -520,6 +853,9 @@ def get_task_schema():
520
853
  'service': {
521
854
  'type': 'object',
522
855
  },
856
+ 'pool': {
857
+ 'type': 'object',
858
+ },
523
859
  'setup': {
524
860
  'type': 'string',
525
861
  },
@@ -537,6 +873,17 @@ def get_task_schema():
537
873
  },
538
874
  'additionalProperties': False,
539
875
  },
876
+ 'secrets': {
877
+ 'type': 'object',
878
+ 'required': [],
879
+ 'patternProperties': {
880
+ # Checks secret keys are valid env var names.
881
+ '^[a-zA-Z_][a-zA-Z0-9_]*$': {
882
+ 'type': ['string', 'null']
883
+ }
884
+ },
885
+ 'additionalProperties': False,
886
+ },
540
887
  # inputs and outputs are experimental
541
888
  'inputs': {
542
889
  'type': 'object',
@@ -560,6 +907,17 @@ def get_task_schema():
560
907
  'config': _filter_schema(
561
908
  get_config_schema(),
562
909
  constants.OVERRIDEABLE_CONFIG_KEYS_IN_TASK),
910
+ # volumes config is validated separately using get_volume_schema
911
+ 'volumes': {
912
+ 'type': 'object',
913
+ },
914
+ 'volume_mounts': {
915
+ 'type': 'array',
916
+ 'items': get_volume_mount_schema(),
917
+ },
918
+ '_metadata': {
919
+ 'type': 'object',
920
+ },
563
921
  **_experimental_task_schema(),
564
922
  }
565
923
  }
@@ -644,7 +1002,7 @@ _LABELS_SCHEMA = {
644
1002
  }
645
1003
  }
646
1004
 
647
- _PRORPERTY_NAME_OR_CLUSTER_NAME_TO_PROPERTY = {
1005
+ _PROPERTY_NAME_OR_CLUSTER_NAME_TO_PROPERTY = {
648
1006
  'oneOf': [
649
1007
  {
650
1008
  'type': 'string'
@@ -712,11 +1070,97 @@ _REMOTE_IDENTITY_SCHEMA_KUBERNETES = {
712
1070
  },
713
1071
  }
714
1072
 
1073
+ _CONTEXT_CONFIG_SCHEMA_KUBERNETES = {
1074
+ # TODO(kevin): Remove 'networking' in v0.13.0.
1075
+ 'networking': {
1076
+ 'type': 'string',
1077
+ 'case_insensitive_enum': [
1078
+ type.value for type in kubernetes_enums.KubernetesNetworkingMode
1079
+ ],
1080
+ },
1081
+ 'ports': {
1082
+ 'type': 'string',
1083
+ 'case_insensitive_enum': [
1084
+ type.value for type in kubernetes_enums.KubernetesPortMode
1085
+ ],
1086
+ },
1087
+ 'pod_config': {
1088
+ 'type': 'object',
1089
+ 'required': [],
1090
+ # Allow arbitrary keys since validating pod spec is hard
1091
+ 'additionalProperties': True,
1092
+ },
1093
+ 'custom_metadata': {
1094
+ 'type': 'object',
1095
+ 'required': [],
1096
+ # Allow arbitrary keys since validating metadata is hard
1097
+ 'additionalProperties': True,
1098
+ # Disallow 'name' and 'namespace' keys in this dict
1099
+ 'not': {
1100
+ 'anyOf': [{
1101
+ 'required': ['name']
1102
+ }, {
1103
+ 'required': ['namespace']
1104
+ }]
1105
+ },
1106
+ },
1107
+ 'provision_timeout': {
1108
+ 'type': 'integer',
1109
+ },
1110
+ 'autoscaler': {
1111
+ 'type': 'string',
1112
+ 'case_insensitive_enum': [
1113
+ type.value for type in kubernetes_enums.KubernetesAutoscalerType
1114
+ ],
1115
+ },
1116
+ 'high_availability': {
1117
+ 'type': 'object',
1118
+ 'required': [],
1119
+ 'additionalProperties': False,
1120
+ 'properties': {
1121
+ 'storage_class_name': {
1122
+ 'type': 'string',
1123
+ }
1124
+ },
1125
+ },
1126
+ 'kueue': {
1127
+ 'type': 'object',
1128
+ 'required': [],
1129
+ 'additionalProperties': False,
1130
+ 'properties': {
1131
+ 'local_queue_name': {
1132
+ 'type': 'string',
1133
+ },
1134
+ },
1135
+ },
1136
+ 'dws': {
1137
+ 'type': 'object',
1138
+ 'required': [],
1139
+ 'additionalProperties': False,
1140
+ 'properties': {
1141
+ 'enabled': {
1142
+ 'type': 'boolean',
1143
+ },
1144
+ # Only used when Kueue is enabled.
1145
+ 'max_run_duration': {
1146
+ 'anyOf': [{
1147
+ 'type': 'string',
1148
+ 'pattern': constants.TIME_PATTERN,
1149
+ }, {
1150
+ 'type': 'integer',
1151
+ }]
1152
+ },
1153
+ },
1154
+ },
1155
+ 'remote_identity': {
1156
+ 'type': 'string',
1157
+ }
1158
+ }
1159
+
715
1160
 
716
1161
  def get_config_schema():
717
1162
  # pylint: disable=import-outside-toplevel
718
- from sky.clouds import service_catalog
719
- from sky.utils import kubernetes_enums
1163
+ from sky.server import daemons
720
1164
 
721
1165
  resources_schema = {
722
1166
  k: v
@@ -725,53 +1169,48 @@ def get_config_schema():
725
1169
  if k != '$schema'
726
1170
  }
727
1171
  resources_schema['properties'].pop('ports')
728
- autostop_schema = {
729
- 'anyOf': [
730
- {
731
- # Use boolean to disable autostop completely, e.g.
732
- # autostop: false
733
- 'type': 'boolean',
734
- },
735
- {
736
- 'type': 'object',
737
- 'required': [],
738
- 'additionalProperties': False,
739
- 'properties': {
740
- 'idle_minutes': {
741
- 'type': 'integer',
742
- 'minimum': 0,
743
- },
744
- 'down': {
745
- 'type': 'boolean',
746
- },
747
- },
748
- },
749
- ],
750
- }
751
- controller_resources_schema = {
752
- 'type': 'object',
753
- 'required': [],
754
- 'additionalProperties': False,
755
- 'properties': {
756
- 'controller': {
757
- 'type': 'object',
758
- 'required': [],
759
- 'additionalProperties': False,
760
- 'properties': {
761
- 'resources': resources_schema,
762
- 'high_availability': {
763
- 'type': 'boolean',
1172
+
1173
+ def _get_controller_schema():
1174
+ return {
1175
+ 'type': 'object',
1176
+ 'required': [],
1177
+ 'additionalProperties': False,
1178
+ 'properties': {
1179
+ 'controller': {
1180
+ 'type': 'object',
1181
+ 'required': [],
1182
+ 'additionalProperties': False,
1183
+ 'properties': {
1184
+ 'resources': resources_schema,
1185
+ 'high_availability': {
1186
+ 'type': 'boolean',
1187
+ 'default': False,
1188
+ },
1189
+ 'autostop': _AUTOSTOP_SCHEMA,
1190
+ 'consolidation_mode': {
1191
+ 'type': 'boolean',
1192
+ 'default': False,
1193
+ },
1194
+ 'controller_logs_gc_retention_hours': {
1195
+ 'type': 'integer',
1196
+ },
1197
+ 'task_logs_gc_retention_hours': {
1198
+ 'type': 'integer',
1199
+ },
764
1200
  },
765
- 'autostop': autostop_schema,
766
- }
767
- },
768
- 'bucket': {
769
- 'type': 'string',
770
- 'pattern': '^(https|s3|gs|r2|cos)://.+',
771
- 'required': [],
1201
+ },
1202
+ 'bucket': {
1203
+ 'type': 'string',
1204
+ 'pattern': '^(https|s3|gs|r2|cos)://.+',
1205
+ 'required': [],
1206
+ },
1207
+ 'force_disable_cloud_bucket': {
1208
+ 'type': 'boolean',
1209
+ 'default': False,
1210
+ },
772
1211
  }
773
1212
  }
774
- }
1213
+
775
1214
  cloud_configs = {
776
1215
  'aws': {
777
1216
  'type': 'object',
@@ -790,8 +1229,11 @@ def get_config_schema():
790
1229
  'disk_encrypted': {
791
1230
  'type': 'boolean',
792
1231
  },
1232
+ 'ssh_user': {
1233
+ 'type': 'string',
1234
+ },
793
1235
  'security_group_name':
794
- (_PRORPERTY_NAME_OR_CLUSTER_NAME_TO_PROPERTY),
1236
+ (_PROPERTY_NAME_OR_CLUSTER_NAME_TO_PROPERTY),
795
1237
  'vpc_name': {
796
1238
  'oneOf': [{
797
1239
  'type': 'string',
@@ -799,6 +1241,22 @@ def get_config_schema():
799
1241
  'type': 'null',
800
1242
  }],
801
1243
  },
1244
+ 'use_ssm': {
1245
+ 'type': 'boolean',
1246
+ },
1247
+ 'post_provision_runcmd': {
1248
+ 'type': 'array',
1249
+ 'items': {
1250
+ 'oneOf': [{
1251
+ 'type': 'string'
1252
+ }, {
1253
+ 'type': 'array',
1254
+ 'items': {
1255
+ 'type': 'string'
1256
+ }
1257
+ }]
1258
+ },
1259
+ },
802
1260
  **_LABELS_SCHEMA,
803
1261
  **_NETWORK_CONFIG_SCHEMA,
804
1262
  },
@@ -837,6 +1295,12 @@ def get_config_schema():
837
1295
  'enable_gvnic': {
838
1296
  'type': 'boolean'
839
1297
  },
1298
+ 'enable_gpu_direct': {
1299
+ 'type': 'boolean'
1300
+ },
1301
+ 'placement_policy': {
1302
+ 'type': 'string',
1303
+ },
840
1304
  'vpc_name': {
841
1305
  'oneOf': [
842
1306
  {
@@ -874,91 +1338,82 @@ def get_config_schema():
874
1338
  'additionalProperties': False,
875
1339
  'properties': {
876
1340
  'allowed_contexts': {
1341
+ 'oneOf': [{
1342
+ 'type': 'array',
1343
+ 'items': {
1344
+ 'type': 'string',
1345
+ },
1346
+ }, {
1347
+ 'type': 'string',
1348
+ 'pattern': '^all$'
1349
+ }]
1350
+ },
1351
+ 'context_configs': {
1352
+ 'type': 'object',
1353
+ 'required': [],
1354
+ 'properties': {},
1355
+ # Properties are kubernetes context names.
1356
+ 'additionalProperties': {
1357
+ 'type': 'object',
1358
+ 'required': [],
1359
+ 'additionalProperties': False,
1360
+ 'properties': {
1361
+ **_CONTEXT_CONFIG_SCHEMA_KUBERNETES,
1362
+ },
1363
+ },
1364
+ },
1365
+ **_CONTEXT_CONFIG_SCHEMA_KUBERNETES,
1366
+ }
1367
+ },
1368
+ 'ssh': {
1369
+ 'type': 'object',
1370
+ 'required': [],
1371
+ 'additionalProperties': False,
1372
+ 'properties': {
1373
+ 'allowed_node_pools': {
877
1374
  'type': 'array',
878
1375
  'items': {
879
1376
  'type': 'string',
880
1377
  },
881
1378
  },
882
- 'networking': {
883
- 'type': 'string',
884
- 'case_insensitive_enum': [
885
- type.value
886
- for type in kubernetes_enums.KubernetesNetworkingMode
887
- ]
888
- },
889
- 'ports': {
890
- 'type': 'string',
891
- 'case_insensitive_enum': [
892
- type.value
893
- for type in kubernetes_enums.KubernetesPortMode
894
- ]
895
- },
896
1379
  'pod_config': {
897
1380
  'type': 'object',
898
1381
  'required': [],
899
1382
  # Allow arbitrary keys since validating pod spec is hard
900
1383
  'additionalProperties': True,
901
1384
  },
902
- 'custom_metadata': {
903
- 'type': 'object',
904
- 'required': [],
905
- # Allow arbitrary keys since validating metadata is hard
906
- 'additionalProperties': True,
907
- # Disallow 'name' and 'namespace' keys in this dict
908
- 'not': {
909
- 'anyOf': [{
910
- 'required': ['name']
911
- }, {
912
- 'required': ['namespace']
913
- }]
914
- }
915
- },
916
- 'provision_timeout': {
917
- 'type': 'integer',
918
- },
919
- 'autoscaler': {
920
- 'type': 'string',
921
- 'case_insensitive_enum': [
922
- type.value
923
- for type in kubernetes_enums.KubernetesAutoscalerType
924
- ]
925
- },
926
- 'high_availability': {
927
- 'type': 'object',
928
- 'required': [],
929
- 'additionalProperties': False,
930
- 'properties': {
931
- 'storage_class_name': {
932
- 'type': 'string',
933
- }
934
- }
935
- },
936
1385
  }
937
1386
  },
938
1387
  'oci': {
939
1388
  'type': 'object',
940
1389
  'required': [],
941
- 'properties': {},
942
- # Properties are either 'default' or a region name.
943
- 'additionalProperties': {
944
- 'type': 'object',
945
- 'required': [],
946
- 'additionalProperties': False,
947
- 'properties': {
948
- 'compartment_ocid': {
949
- 'type': 'string',
950
- },
951
- 'image_tag_general': {
952
- 'type': 'string',
953
- },
954
- 'image_tag_gpu': {
955
- 'type': 'string',
956
- },
957
- 'vcn_ocid': {
958
- 'type': 'string',
959
- },
960
- 'vcn_subnet': {
961
- 'type': 'string',
1390
+ 'properties': {
1391
+ 'region_configs': {
1392
+ 'type': 'object',
1393
+ 'required': [],
1394
+ 'properties': {},
1395
+ # Properties are either 'default' or a region name.
1396
+ 'additionalProperties': {
1397
+ 'type': 'object',
1398
+ 'required': [],
1399
+ 'additionalProperties': False,
1400
+ 'properties': {
1401
+ 'compartment_ocid': {
1402
+ 'type': 'string',
1403
+ },
1404
+ 'image_tag_general': {
1405
+ 'type': 'string',
1406
+ },
1407
+ 'image_tag_gpu': {
1408
+ 'type': 'string',
1409
+ },
1410
+ 'vcn_ocid': {
1411
+ 'type': 'string',
1412
+ },
1413
+ 'vcn_subnet': {
1414
+ 'type': 'string',
1415
+ },
1416
+ }
962
1417
  },
963
1418
  }
964
1419
  },
@@ -966,18 +1421,54 @@ def get_config_schema():
966
1421
  'nebius': {
967
1422
  'type': 'object',
968
1423
  'required': [],
969
- 'properties': {},
970
- 'additionalProperties': {
971
- 'type': 'object',
972
- 'required': [],
973
- 'additionalProperties': False,
974
- 'properties': {
975
- 'project_id': {
976
- 'type': 'string',
977
- },
978
- 'fabric': {
979
- 'type': 'string',
980
- },
1424
+ 'properties': {
1425
+ **_NETWORK_CONFIG_SCHEMA, 'use_static_ip_address': {
1426
+ 'type': 'boolean',
1427
+ },
1428
+ 'tenant_id': {
1429
+ 'type': 'string',
1430
+ },
1431
+ 'domain': {
1432
+ 'type': 'string',
1433
+ },
1434
+ 'region_configs': {
1435
+ 'type': 'object',
1436
+ 'required': [],
1437
+ 'properties': {},
1438
+ 'additionalProperties': {
1439
+ 'type': 'object',
1440
+ 'required': [],
1441
+ 'additionalProperties': False,
1442
+ 'properties': {
1443
+ 'project_id': {
1444
+ 'type': 'string',
1445
+ },
1446
+ 'fabric': {
1447
+ 'type': 'string',
1448
+ },
1449
+ 'filesystems': {
1450
+ 'type': 'array',
1451
+ 'items': {
1452
+ 'type': 'object',
1453
+ 'additionalProperties': False,
1454
+ 'properties': {
1455
+ 'filesystem_id': {
1456
+ 'type': 'string',
1457
+ },
1458
+ 'attach_mode': {
1459
+ 'type': 'string',
1460
+ 'case_sensitive_enum': [
1461
+ 'READ_WRITE', 'READ_ONLY'
1462
+ ]
1463
+ },
1464
+ 'mount_path': {
1465
+ 'type': 'string',
1466
+ }
1467
+ }
1468
+ }
1469
+ },
1470
+ },
1471
+ }
981
1472
  }
982
1473
  },
983
1474
  }
@@ -985,9 +1476,17 @@ def get_config_schema():
985
1476
 
986
1477
  admin_policy_schema = {
987
1478
  'type': 'string',
988
- # Check regex to be a valid python module path
989
- 'pattern': (r'^[a-zA-Z_][a-zA-Z0-9_]*'
990
- r'(\.[a-zA-Z_][a-zA-Z0-9_]*)+$'),
1479
+ 'anyOf': [
1480
+ {
1481
+ # Check regex to be a valid python module path
1482
+ 'pattern': (r'^[a-zA-Z_][a-zA-Z0-9_]*'
1483
+ r'(\.[a-zA-Z_][a-zA-Z0-9_]*)+$'),
1484
+ },
1485
+ {
1486
+ # Check for valid HTTP/HTTPS URL
1487
+ 'pattern': r'^https?://.*$',
1488
+ }
1489
+ ]
991
1490
  }
992
1491
 
993
1492
  allowed_clouds = {
@@ -996,7 +1495,7 @@ def get_config_schema():
996
1495
  'items': {
997
1496
  'type': 'string',
998
1497
  'case_insensitive_enum':
999
- (list(service_catalog.ALL_CLOUDS) + ['cloudflare'])
1498
+ (list(constants.ALL_CLOUDS) + ['cloudflare'])
1000
1499
  }
1001
1500
  }
1002
1501
 
@@ -1028,6 +1527,27 @@ def get_config_schema():
1028
1527
  }
1029
1528
  }
1030
1529
 
1530
+ daemon_config = {
1531
+ 'type': 'object',
1532
+ 'required': [],
1533
+ 'properties': {
1534
+ 'log_level': {
1535
+ 'type': 'string',
1536
+ 'case_insensitive_enum': ['DEBUG', 'INFO', 'WARNING'],
1537
+ },
1538
+ }
1539
+ }
1540
+
1541
+ daemon_schema = {
1542
+ 'type': 'object',
1543
+ 'required': [],
1544
+ 'additionalProperties': False,
1545
+ 'properties': {}
1546
+ }
1547
+
1548
+ for daemon in daemons.INTERNAL_REQUEST_DAEMONS:
1549
+ daemon_schema['properties'][daemon.id] = daemon_config
1550
+
1031
1551
  api_server = {
1032
1552
  'type': 'object',
1033
1553
  'required': [],
@@ -1038,14 +1558,239 @@ def get_config_schema():
1038
1558
  # Apply validation for URL
1039
1559
  'pattern': r'^https?://.*$',
1040
1560
  },
1561
+ 'service_account_token': {
1562
+ 'anyOf': [
1563
+ {
1564
+ 'type': 'string',
1565
+ # Validate that token starts with sky_ prefix
1566
+ 'pattern': r'^sky_.+$',
1567
+ },
1568
+ {
1569
+ 'type': 'null',
1570
+ }
1571
+ ]
1572
+ },
1573
+ 'requests_retention_hours': {
1574
+ 'type': 'integer',
1575
+ },
1576
+ 'cluster_event_retention_hours': {
1577
+ 'type': 'number',
1578
+ },
1579
+ 'cluster_debug_event_retention_hours': {
1580
+ 'type': 'number',
1581
+ },
1041
1582
  }
1042
1583
  }
1043
1584
 
1585
+ rbac_schema = {
1586
+ 'type': 'object',
1587
+ 'required': [],
1588
+ 'additionalProperties': False,
1589
+ 'properties': {
1590
+ 'default_role': {
1591
+ 'type': 'string',
1592
+ 'case_insensitive_enum': ['admin', 'user']
1593
+ },
1594
+ },
1595
+ }
1596
+
1597
+ workspace_schema = {'type': 'string'}
1598
+
1599
+ allowed_workspace_cloud_names = list(constants.ALL_CLOUDS) + ['cloudflare']
1600
+ # Create pattern for not supported clouds, i.e.
1601
+ # all clouds except aws, gcp, kubernetes, ssh, nebius
1602
+ not_supported_clouds = [
1603
+ cloud for cloud in allowed_workspace_cloud_names
1604
+ if cloud.lower() not in ['aws', 'gcp', 'kubernetes', 'ssh', 'nebius']
1605
+ ]
1606
+ not_supported_cloud_regex = '|'.join(not_supported_clouds)
1607
+ workspaces_schema = {
1608
+ 'type': 'object',
1609
+ 'required': [],
1610
+ # each key is a workspace name
1611
+ 'additionalProperties': {
1612
+ 'type': 'object',
1613
+ 'additionalProperties': False,
1614
+ 'patternProperties': {
1615
+ # Pattern for clouds with no workspace-specific config -
1616
+ # only allow 'disabled' property.
1617
+ f'^({not_supported_cloud_regex})$': {
1618
+ 'type': 'object',
1619
+ 'additionalProperties': False,
1620
+ 'properties': {
1621
+ 'disabled': {
1622
+ 'type': 'boolean'
1623
+ }
1624
+ },
1625
+ },
1626
+ },
1627
+ 'properties': {
1628
+ # Explicit definition for GCP allows both project_id and
1629
+ # disabled
1630
+ 'private': {
1631
+ 'type': 'boolean',
1632
+ },
1633
+ 'allowed_users': {
1634
+ 'type': 'array',
1635
+ 'items': {
1636
+ 'type': 'string',
1637
+ },
1638
+ },
1639
+ 'gcp': {
1640
+ 'type': 'object',
1641
+ 'properties': {
1642
+ 'project_id': {
1643
+ 'type': 'string'
1644
+ },
1645
+ 'disabled': {
1646
+ 'type': 'boolean'
1647
+ }
1648
+ },
1649
+ 'additionalProperties': False,
1650
+ },
1651
+ 'aws': {
1652
+ 'type': 'object',
1653
+ 'properties': {
1654
+ 'profile': {
1655
+ 'type': 'string'
1656
+ },
1657
+ 'disabled': {
1658
+ 'type': 'boolean'
1659
+ },
1660
+ },
1661
+ 'additionalProperties': False,
1662
+ },
1663
+ 'ssh': {
1664
+ 'type': 'object',
1665
+ 'required': [],
1666
+ 'properties': {
1667
+ 'allowed_node_pools': {
1668
+ 'type': 'array',
1669
+ 'items': {
1670
+ 'type': 'string',
1671
+ },
1672
+ },
1673
+ 'disabled': {
1674
+ 'type': 'boolean'
1675
+ },
1676
+ },
1677
+ 'additionalProperties': False,
1678
+ },
1679
+ 'kubernetes': {
1680
+ 'type': 'object',
1681
+ 'required': [],
1682
+ 'properties': {
1683
+ 'allowed_contexts': {
1684
+ 'oneOf': [{
1685
+ 'type': 'array',
1686
+ 'items': {
1687
+ 'type': 'string',
1688
+ },
1689
+ }, {
1690
+ 'type': 'string',
1691
+ 'pattern': '^all$'
1692
+ }]
1693
+ },
1694
+ 'disabled': {
1695
+ 'type': 'boolean'
1696
+ },
1697
+ },
1698
+ 'additionalProperties': False,
1699
+ },
1700
+ 'nebius': {
1701
+ 'type': 'object',
1702
+ 'required': [],
1703
+ 'properties': {
1704
+ 'credentials_file_path': {
1705
+ 'type': 'string',
1706
+ },
1707
+ 'tenant_id': {
1708
+ 'type': 'string',
1709
+ },
1710
+ 'domain': {
1711
+ 'type': 'string',
1712
+ },
1713
+ 'disabled': {
1714
+ 'type': 'boolean'
1715
+ },
1716
+ },
1717
+ 'additionalProperties': False,
1718
+ },
1719
+ },
1720
+ },
1721
+ }
1722
+
1723
+ provision_configs = {
1724
+ 'type': 'object',
1725
+ 'required': [],
1726
+ 'additionalProperties': False,
1727
+ 'properties': {
1728
+ 'ssh_timeout': {
1729
+ 'type': 'integer',
1730
+ 'minimum': 1,
1731
+ },
1732
+ }
1733
+ }
1734
+
1735
+ logs_schema = {
1736
+ 'type': 'object',
1737
+ 'required': ['store'],
1738
+ 'additionalProperties': False,
1739
+ 'properties': {
1740
+ 'store': {
1741
+ 'type': 'string',
1742
+ 'case_insensitive_enum': ['gcp', 'aws'],
1743
+ },
1744
+ 'gcp': {
1745
+ 'type': 'object',
1746
+ 'properties': {
1747
+ 'project_id': {
1748
+ 'type': 'string',
1749
+ },
1750
+ 'credentials_file': {
1751
+ 'type': 'string',
1752
+ },
1753
+ 'additional_labels': {
1754
+ 'type': 'object',
1755
+ 'additionalProperties': {
1756
+ 'type': 'string',
1757
+ },
1758
+ },
1759
+ },
1760
+ },
1761
+ 'aws': {
1762
+ 'type': 'object',
1763
+ 'properties': {
1764
+ 'region': {
1765
+ 'type': 'string',
1766
+ },
1767
+ 'credentials_file': {
1768
+ 'type': 'string',
1769
+ },
1770
+ 'log_group_name': {
1771
+ 'type': 'string',
1772
+ },
1773
+ 'log_stream_prefix': {
1774
+ 'type': 'string',
1775
+ },
1776
+ 'auto_create_group': {
1777
+ 'type': 'boolean',
1778
+ },
1779
+ 'additional_tags': {
1780
+ 'type': 'object',
1781
+ 'additionalProperties': {
1782
+ 'type': 'string',
1783
+ },
1784
+ },
1785
+ },
1786
+ },
1787
+ },
1788
+ }
1789
+
1044
1790
  for cloud, config in cloud_configs.items():
1045
1791
  if cloud == 'aws':
1046
- config['properties'].update({
1047
- 'remote_identity': _PRORPERTY_NAME_OR_CLUSTER_NAME_TO_PROPERTY
1048
- })
1792
+ config['properties'].update(
1793
+ {'remote_identity': _PROPERTY_NAME_OR_CLUSTER_NAME_TO_PROPERTY})
1049
1794
  elif cloud == 'kubernetes':
1050
1795
  config['properties'].update(_REMOTE_IDENTITY_SCHEMA_KUBERNETES)
1051
1796
  else:
@@ -1056,13 +1801,26 @@ def get_config_schema():
1056
1801
  'required': [],
1057
1802
  'additionalProperties': False,
1058
1803
  'properties': {
1059
- 'jobs': controller_resources_schema,
1060
- 'serve': controller_resources_schema,
1804
+ # TODO Replace this with whatever syang cooks up
1805
+ 'workspace': {
1806
+ 'type': 'string',
1807
+ },
1808
+ 'db': {
1809
+ 'type': 'string',
1810
+ },
1811
+ 'jobs': _get_controller_schema(),
1812
+ 'serve': _get_controller_schema(),
1061
1813
  'allowed_clouds': allowed_clouds,
1062
1814
  'admin_policy': admin_policy_schema,
1063
1815
  'docker': docker_configs,
1064
1816
  'nvidia_gpus': gpu_configs,
1065
1817
  'api_server': api_server,
1818
+ 'active_workspace': workspace_schema,
1819
+ 'workspaces': workspaces_schema,
1820
+ 'provision': provision_configs,
1821
+ 'rbac': rbac_schema,
1822
+ 'logs': logs_schema,
1823
+ 'daemons': daemon_schema,
1066
1824
  **cloud_configs,
1067
1825
  },
1068
1826
  }