skypilot-nightly 1.0.0.dev20250502__py3-none-any.whl → 1.0.0.dev20251203__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (546) hide show
  1. sky/__init__.py +22 -6
  2. sky/adaptors/aws.py +81 -16
  3. sky/adaptors/common.py +25 -2
  4. sky/adaptors/coreweave.py +278 -0
  5. sky/adaptors/do.py +8 -2
  6. sky/adaptors/gcp.py +11 -0
  7. sky/adaptors/hyperbolic.py +8 -0
  8. sky/adaptors/ibm.py +5 -2
  9. sky/adaptors/kubernetes.py +149 -18
  10. sky/adaptors/nebius.py +173 -30
  11. sky/adaptors/primeintellect.py +1 -0
  12. sky/adaptors/runpod.py +68 -0
  13. sky/adaptors/seeweb.py +183 -0
  14. sky/adaptors/shadeform.py +89 -0
  15. sky/admin_policy.py +187 -4
  16. sky/authentication.py +179 -225
  17. sky/backends/__init__.py +4 -2
  18. sky/backends/backend.py +22 -9
  19. sky/backends/backend_utils.py +1323 -397
  20. sky/backends/cloud_vm_ray_backend.py +1749 -1029
  21. sky/backends/docker_utils.py +1 -1
  22. sky/backends/local_docker_backend.py +11 -6
  23. sky/backends/task_codegen.py +633 -0
  24. sky/backends/wheel_utils.py +55 -9
  25. sky/{clouds/service_catalog → catalog}/__init__.py +21 -19
  26. sky/{clouds/service_catalog → catalog}/aws_catalog.py +27 -8
  27. sky/{clouds/service_catalog → catalog}/azure_catalog.py +10 -7
  28. sky/{clouds/service_catalog → catalog}/common.py +90 -49
  29. sky/{clouds/service_catalog → catalog}/cudo_catalog.py +8 -5
  30. sky/{clouds/service_catalog → catalog}/data_fetchers/analyze.py +1 -1
  31. sky/{clouds/service_catalog → catalog}/data_fetchers/fetch_aws.py +116 -80
  32. sky/{clouds/service_catalog → catalog}/data_fetchers/fetch_cudo.py +38 -38
  33. sky/{clouds/service_catalog → catalog}/data_fetchers/fetch_gcp.py +70 -16
  34. sky/catalog/data_fetchers/fetch_hyperbolic.py +136 -0
  35. sky/{clouds/service_catalog → catalog}/data_fetchers/fetch_lambda_cloud.py +1 -0
  36. sky/catalog/data_fetchers/fetch_nebius.py +338 -0
  37. sky/catalog/data_fetchers/fetch_runpod.py +698 -0
  38. sky/catalog/data_fetchers/fetch_seeweb.py +329 -0
  39. sky/catalog/data_fetchers/fetch_shadeform.py +142 -0
  40. sky/{clouds/service_catalog → catalog}/data_fetchers/fetch_vast.py +1 -1
  41. sky/{clouds/service_catalog → catalog}/data_fetchers/fetch_vsphere.py +1 -1
  42. sky/{clouds/service_catalog → catalog}/do_catalog.py +5 -2
  43. sky/{clouds/service_catalog → catalog}/fluidstack_catalog.py +6 -3
  44. sky/{clouds/service_catalog → catalog}/gcp_catalog.py +41 -15
  45. sky/catalog/hyperbolic_catalog.py +136 -0
  46. sky/{clouds/service_catalog → catalog}/ibm_catalog.py +9 -6
  47. sky/{clouds/service_catalog → catalog}/kubernetes_catalog.py +36 -24
  48. sky/{clouds/service_catalog → catalog}/lambda_catalog.py +9 -6
  49. sky/{clouds/service_catalog → catalog}/nebius_catalog.py +9 -7
  50. sky/{clouds/service_catalog → catalog}/oci_catalog.py +9 -6
  51. sky/{clouds/service_catalog → catalog}/paperspace_catalog.py +5 -2
  52. sky/catalog/primeintellect_catalog.py +95 -0
  53. sky/{clouds/service_catalog → catalog}/runpod_catalog.py +11 -4
  54. sky/{clouds/service_catalog → catalog}/scp_catalog.py +9 -6
  55. sky/catalog/seeweb_catalog.py +184 -0
  56. sky/catalog/shadeform_catalog.py +165 -0
  57. sky/catalog/ssh_catalog.py +167 -0
  58. sky/{clouds/service_catalog → catalog}/vast_catalog.py +6 -3
  59. sky/{clouds/service_catalog → catalog}/vsphere_catalog.py +5 -2
  60. sky/check.py +533 -185
  61. sky/cli.py +5 -5975
  62. sky/client/{cli.py → cli/command.py} +2591 -1956
  63. sky/client/cli/deprecation_utils.py +99 -0
  64. sky/client/cli/flags.py +359 -0
  65. sky/client/cli/table_utils.py +322 -0
  66. sky/client/cli/utils.py +79 -0
  67. sky/client/common.py +78 -32
  68. sky/client/oauth.py +82 -0
  69. sky/client/sdk.py +1219 -319
  70. sky/client/sdk_async.py +827 -0
  71. sky/client/service_account_auth.py +47 -0
  72. sky/cloud_stores.py +82 -3
  73. sky/clouds/__init__.py +13 -0
  74. sky/clouds/aws.py +564 -164
  75. sky/clouds/azure.py +105 -83
  76. sky/clouds/cloud.py +140 -40
  77. sky/clouds/cudo.py +68 -50
  78. sky/clouds/do.py +66 -48
  79. sky/clouds/fluidstack.py +63 -44
  80. sky/clouds/gcp.py +339 -110
  81. sky/clouds/hyperbolic.py +293 -0
  82. sky/clouds/ibm.py +70 -49
  83. sky/clouds/kubernetes.py +570 -162
  84. sky/clouds/lambda_cloud.py +74 -54
  85. sky/clouds/nebius.py +210 -81
  86. sky/clouds/oci.py +88 -66
  87. sky/clouds/paperspace.py +61 -44
  88. sky/clouds/primeintellect.py +317 -0
  89. sky/clouds/runpod.py +164 -74
  90. sky/clouds/scp.py +89 -86
  91. sky/clouds/seeweb.py +477 -0
  92. sky/clouds/shadeform.py +400 -0
  93. sky/clouds/ssh.py +263 -0
  94. sky/clouds/utils/aws_utils.py +10 -4
  95. sky/clouds/utils/gcp_utils.py +87 -11
  96. sky/clouds/utils/oci_utils.py +38 -14
  97. sky/clouds/utils/scp_utils.py +231 -167
  98. sky/clouds/vast.py +99 -77
  99. sky/clouds/vsphere.py +51 -40
  100. sky/core.py +375 -173
  101. sky/dag.py +15 -0
  102. sky/dashboard/out/404.html +1 -1
  103. sky/dashboard/out/_next/static/96_E2yl3QAiIJGOYCkSpB/_buildManifest.js +1 -0
  104. sky/dashboard/out/_next/static/chunks/1141-e6aa9ab418717c59.js +11 -0
  105. sky/dashboard/out/_next/static/chunks/1272-1ef0bf0237faccdb.js +1 -0
  106. sky/dashboard/out/_next/static/chunks/1871-7e202677c42f43fe.js +6 -0
  107. sky/dashboard/out/_next/static/chunks/2260-7703229c33c5ebd5.js +1 -0
  108. sky/dashboard/out/_next/static/chunks/2350.fab69e61bac57b23.js +1 -0
  109. sky/dashboard/out/_next/static/chunks/2369.fc20f0c2c8ed9fe7.js +15 -0
  110. sky/dashboard/out/_next/static/chunks/2755.edd818326d489a1d.js +26 -0
  111. sky/dashboard/out/_next/static/chunks/3294.20a8540fe697d5ee.js +1 -0
  112. sky/dashboard/out/_next/static/chunks/3785.7e245f318f9d1121.js +1 -0
  113. sky/dashboard/out/_next/static/chunks/3800-7b45f9fbb6308557.js +1 -0
  114. sky/dashboard/out/_next/static/chunks/3850-ff4a9a69d978632b.js +1 -0
  115. sky/dashboard/out/_next/static/chunks/3937.210053269f121201.js +1 -0
  116. sky/dashboard/out/_next/static/chunks/4725.172ede95d1b21022.js +1 -0
  117. sky/dashboard/out/_next/static/chunks/4937.a2baa2df5572a276.js +15 -0
  118. sky/dashboard/out/_next/static/chunks/5739-d67458fcb1386c92.js +8 -0
  119. sky/dashboard/out/_next/static/chunks/6130-2be46d70a38f1e82.js +1 -0
  120. sky/dashboard/out/_next/static/chunks/616-3d59f75e2ccf9321.js +39 -0
  121. sky/dashboard/out/_next/static/chunks/6212-7bd06f60ba693125.js +13 -0
  122. sky/dashboard/out/_next/static/chunks/6856-8f27d1c10c98def8.js +1 -0
  123. sky/dashboard/out/_next/static/chunks/6989-01359c57e018caa4.js +1 -0
  124. sky/dashboard/out/_next/static/chunks/6990-9146207c4567fdfd.js +1 -0
  125. sky/dashboard/out/_next/static/chunks/7359-c8d04e06886000b3.js +30 -0
  126. sky/dashboard/out/_next/static/chunks/7411-b15471acd2cba716.js +41 -0
  127. sky/dashboard/out/_next/static/chunks/7615-019513abc55b3b47.js +1 -0
  128. sky/dashboard/out/_next/static/chunks/8640.5b9475a2d18c5416.js +16 -0
  129. sky/dashboard/out/_next/static/chunks/8969-452f9d5cbdd2dc73.js +1 -0
  130. sky/dashboard/out/_next/static/chunks/9025.fa408f3242e9028d.js +6 -0
  131. sky/dashboard/out/_next/static/chunks/9353-cff34f7e773b2e2b.js +1 -0
  132. sky/dashboard/out/_next/static/chunks/9360.a536cf6b1fa42355.js +31 -0
  133. sky/dashboard/out/_next/static/chunks/9847.3aaca6bb33455140.js +30 -0
  134. sky/dashboard/out/_next/static/chunks/fd9d1056-86323a29a8f7e46a.js +1 -0
  135. sky/dashboard/out/_next/static/chunks/framework-cf60a09ccd051a10.js +33 -0
  136. sky/dashboard/out/_next/static/chunks/main-app-587214043926b3cc.js +1 -0
  137. sky/dashboard/out/_next/static/chunks/main-f15ccb73239a3bf1.js +1 -0
  138. sky/dashboard/out/_next/static/chunks/pages/_app-bde01e4a2beec258.js +34 -0
  139. sky/dashboard/out/_next/static/chunks/pages/_error-c66a4e8afc46f17b.js +1 -0
  140. sky/dashboard/out/_next/static/chunks/pages/clusters/[cluster]/[job]-792db96d918c98c9.js +16 -0
  141. sky/dashboard/out/_next/static/chunks/pages/clusters/[cluster]-abfcac9c137aa543.js +1 -0
  142. sky/dashboard/out/_next/static/chunks/pages/clusters-ee39056f9851a3ff.js +1 -0
  143. sky/dashboard/out/_next/static/chunks/pages/config-dfb9bf07b13045f4.js +1 -0
  144. sky/dashboard/out/_next/static/chunks/pages/index-444f1804401f04ea.js +1 -0
  145. sky/dashboard/out/_next/static/chunks/pages/infra/[context]-c0b5935149902e6f.js +1 -0
  146. sky/dashboard/out/_next/static/chunks/pages/infra-aed0ea19df7cf961.js +1 -0
  147. sky/dashboard/out/_next/static/chunks/pages/jobs/[job]-d66997e2bfc837cf.js +16 -0
  148. sky/dashboard/out/_next/static/chunks/pages/jobs/pools/[pool]-9faf940b253e3e06.js +21 -0
  149. sky/dashboard/out/_next/static/chunks/pages/jobs-2072b48b617989c9.js +1 -0
  150. sky/dashboard/out/_next/static/chunks/pages/users-f42674164aa73423.js +1 -0
  151. sky/dashboard/out/_next/static/chunks/pages/volumes-b84b948ff357c43e.js +1 -0
  152. sky/dashboard/out/_next/static/chunks/pages/workspace/new-3f88a1c7e86a3f86.js +1 -0
  153. sky/dashboard/out/_next/static/chunks/pages/workspaces/[name]-84a40f8c7c627fe4.js +1 -0
  154. sky/dashboard/out/_next/static/chunks/pages/workspaces-531b2f8c4bf89f82.js +1 -0
  155. sky/dashboard/out/_next/static/chunks/webpack-64e05f17bf2cf8ce.js +1 -0
  156. sky/dashboard/out/_next/static/css/0748ce22df867032.css +3 -0
  157. sky/dashboard/out/clusters/[cluster]/[job].html +1 -1
  158. sky/dashboard/out/clusters/[cluster].html +1 -1
  159. sky/dashboard/out/clusters.html +1 -1
  160. sky/dashboard/out/config.html +1 -0
  161. sky/dashboard/out/index.html +1 -1
  162. sky/dashboard/out/infra/[context].html +1 -0
  163. sky/dashboard/out/infra.html +1 -0
  164. sky/dashboard/out/jobs/[job].html +1 -1
  165. sky/dashboard/out/jobs/pools/[pool].html +1 -0
  166. sky/dashboard/out/jobs.html +1 -1
  167. sky/dashboard/out/users.html +1 -0
  168. sky/dashboard/out/volumes.html +1 -0
  169. sky/dashboard/out/workspace/new.html +1 -0
  170. sky/dashboard/out/workspaces/[name].html +1 -0
  171. sky/dashboard/out/workspaces.html +1 -0
  172. sky/data/data_utils.py +137 -1
  173. sky/data/mounting_utils.py +269 -84
  174. sky/data/storage.py +1460 -1807
  175. sky/data/storage_utils.py +43 -57
  176. sky/exceptions.py +126 -2
  177. sky/execution.py +216 -63
  178. sky/global_user_state.py +2390 -586
  179. sky/jobs/__init__.py +7 -0
  180. sky/jobs/client/sdk.py +300 -58
  181. sky/jobs/client/sdk_async.py +161 -0
  182. sky/jobs/constants.py +15 -8
  183. sky/jobs/controller.py +848 -275
  184. sky/jobs/file_content_utils.py +128 -0
  185. sky/jobs/log_gc.py +193 -0
  186. sky/jobs/recovery_strategy.py +402 -152
  187. sky/jobs/scheduler.py +314 -189
  188. sky/jobs/server/core.py +836 -255
  189. sky/jobs/server/server.py +156 -115
  190. sky/jobs/server/utils.py +136 -0
  191. sky/jobs/state.py +2109 -706
  192. sky/jobs/utils.py +1306 -215
  193. sky/logs/__init__.py +21 -0
  194. sky/logs/agent.py +108 -0
  195. sky/logs/aws.py +243 -0
  196. sky/logs/gcp.py +91 -0
  197. sky/metrics/__init__.py +0 -0
  198. sky/metrics/utils.py +453 -0
  199. sky/models.py +78 -1
  200. sky/optimizer.py +164 -70
  201. sky/provision/__init__.py +90 -4
  202. sky/provision/aws/config.py +147 -26
  203. sky/provision/aws/instance.py +136 -50
  204. sky/provision/azure/instance.py +11 -6
  205. sky/provision/common.py +13 -1
  206. sky/provision/cudo/cudo_machine_type.py +1 -1
  207. sky/provision/cudo/cudo_utils.py +14 -8
  208. sky/provision/cudo/cudo_wrapper.py +72 -71
  209. sky/provision/cudo/instance.py +10 -6
  210. sky/provision/do/instance.py +10 -6
  211. sky/provision/do/utils.py +4 -3
  212. sky/provision/docker_utils.py +140 -33
  213. sky/provision/fluidstack/instance.py +13 -8
  214. sky/provision/gcp/__init__.py +1 -0
  215. sky/provision/gcp/config.py +301 -19
  216. sky/provision/gcp/constants.py +218 -0
  217. sky/provision/gcp/instance.py +36 -8
  218. sky/provision/gcp/instance_utils.py +18 -4
  219. sky/provision/gcp/volume_utils.py +247 -0
  220. sky/provision/hyperbolic/__init__.py +12 -0
  221. sky/provision/hyperbolic/config.py +10 -0
  222. sky/provision/hyperbolic/instance.py +437 -0
  223. sky/provision/hyperbolic/utils.py +373 -0
  224. sky/provision/instance_setup.py +101 -20
  225. sky/provision/kubernetes/__init__.py +5 -0
  226. sky/provision/kubernetes/config.py +9 -52
  227. sky/provision/kubernetes/constants.py +17 -0
  228. sky/provision/kubernetes/instance.py +919 -280
  229. sky/provision/kubernetes/manifests/fusermount-server-daemonset.yaml +1 -2
  230. sky/provision/kubernetes/network.py +27 -17
  231. sky/provision/kubernetes/network_utils.py +44 -43
  232. sky/provision/kubernetes/utils.py +1221 -534
  233. sky/provision/kubernetes/volume.py +343 -0
  234. sky/provision/lambda_cloud/instance.py +22 -16
  235. sky/provision/nebius/constants.py +50 -0
  236. sky/provision/nebius/instance.py +19 -6
  237. sky/provision/nebius/utils.py +237 -137
  238. sky/provision/oci/instance.py +10 -5
  239. sky/provision/paperspace/instance.py +10 -7
  240. sky/provision/paperspace/utils.py +1 -1
  241. sky/provision/primeintellect/__init__.py +10 -0
  242. sky/provision/primeintellect/config.py +11 -0
  243. sky/provision/primeintellect/instance.py +454 -0
  244. sky/provision/primeintellect/utils.py +398 -0
  245. sky/provision/provisioner.py +117 -36
  246. sky/provision/runpod/__init__.py +5 -0
  247. sky/provision/runpod/instance.py +27 -6
  248. sky/provision/runpod/utils.py +51 -18
  249. sky/provision/runpod/volume.py +214 -0
  250. sky/provision/scp/__init__.py +15 -0
  251. sky/provision/scp/config.py +93 -0
  252. sky/provision/scp/instance.py +707 -0
  253. sky/provision/seeweb/__init__.py +11 -0
  254. sky/provision/seeweb/config.py +13 -0
  255. sky/provision/seeweb/instance.py +812 -0
  256. sky/provision/shadeform/__init__.py +11 -0
  257. sky/provision/shadeform/config.py +12 -0
  258. sky/provision/shadeform/instance.py +351 -0
  259. sky/provision/shadeform/shadeform_utils.py +83 -0
  260. sky/provision/ssh/__init__.py +18 -0
  261. sky/provision/vast/instance.py +13 -8
  262. sky/provision/vast/utils.py +10 -7
  263. sky/provision/volume.py +164 -0
  264. sky/provision/vsphere/common/ssl_helper.py +1 -1
  265. sky/provision/vsphere/common/vapiconnect.py +2 -1
  266. sky/provision/vsphere/common/vim_utils.py +4 -4
  267. sky/provision/vsphere/instance.py +15 -10
  268. sky/provision/vsphere/vsphere_utils.py +17 -20
  269. sky/py.typed +0 -0
  270. sky/resources.py +845 -119
  271. sky/schemas/__init__.py +0 -0
  272. sky/schemas/api/__init__.py +0 -0
  273. sky/schemas/api/responses.py +227 -0
  274. sky/schemas/db/README +4 -0
  275. sky/schemas/db/env.py +90 -0
  276. sky/schemas/db/global_user_state/001_initial_schema.py +124 -0
  277. sky/schemas/db/global_user_state/002_add_workspace_to_cluster_history.py +35 -0
  278. sky/schemas/db/global_user_state/003_fix_initial_revision.py +61 -0
  279. sky/schemas/db/global_user_state/004_is_managed.py +34 -0
  280. sky/schemas/db/global_user_state/005_cluster_event.py +32 -0
  281. sky/schemas/db/global_user_state/006_provision_log.py +41 -0
  282. sky/schemas/db/global_user_state/007_cluster_event_request_id.py +34 -0
  283. sky/schemas/db/global_user_state/008_skylet_ssh_tunnel_metadata.py +34 -0
  284. sky/schemas/db/global_user_state/009_last_activity_and_launched_at.py +89 -0
  285. sky/schemas/db/global_user_state/010_save_ssh_key.py +66 -0
  286. sky/schemas/db/global_user_state/011_is_ephemeral.py +34 -0
  287. sky/schemas/db/kv_cache/001_initial_schema.py +29 -0
  288. sky/schemas/db/script.py.mako +28 -0
  289. sky/schemas/db/serve_state/001_initial_schema.py +67 -0
  290. sky/schemas/db/serve_state/002_yaml_content.py +34 -0
  291. sky/schemas/db/skypilot_config/001_initial_schema.py +30 -0
  292. sky/schemas/db/spot_jobs/001_initial_schema.py +97 -0
  293. sky/schemas/db/spot_jobs/002_cluster_pool.py +42 -0
  294. sky/schemas/db/spot_jobs/003_pool_hash.py +34 -0
  295. sky/schemas/db/spot_jobs/004_job_file_contents.py +42 -0
  296. sky/schemas/db/spot_jobs/005_logs_gc.py +38 -0
  297. sky/schemas/db/spot_jobs/006_controller_pid_started_at.py +34 -0
  298. sky/schemas/db/spot_jobs/007_config_file_content.py +34 -0
  299. sky/schemas/generated/__init__.py +0 -0
  300. sky/schemas/generated/autostopv1_pb2.py +36 -0
  301. sky/schemas/generated/autostopv1_pb2.pyi +43 -0
  302. sky/schemas/generated/autostopv1_pb2_grpc.py +146 -0
  303. sky/schemas/generated/jobsv1_pb2.py +86 -0
  304. sky/schemas/generated/jobsv1_pb2.pyi +254 -0
  305. sky/schemas/generated/jobsv1_pb2_grpc.py +542 -0
  306. sky/schemas/generated/managed_jobsv1_pb2.py +76 -0
  307. sky/schemas/generated/managed_jobsv1_pb2.pyi +278 -0
  308. sky/schemas/generated/managed_jobsv1_pb2_grpc.py +278 -0
  309. sky/schemas/generated/servev1_pb2.py +58 -0
  310. sky/schemas/generated/servev1_pb2.pyi +115 -0
  311. sky/schemas/generated/servev1_pb2_grpc.py +322 -0
  312. sky/serve/autoscalers.py +357 -5
  313. sky/serve/client/impl.py +310 -0
  314. sky/serve/client/sdk.py +47 -139
  315. sky/serve/client/sdk_async.py +130 -0
  316. sky/serve/constants.py +12 -9
  317. sky/serve/controller.py +68 -17
  318. sky/serve/load_balancer.py +106 -60
  319. sky/serve/load_balancing_policies.py +116 -2
  320. sky/serve/replica_managers.py +434 -249
  321. sky/serve/serve_rpc_utils.py +179 -0
  322. sky/serve/serve_state.py +569 -257
  323. sky/serve/serve_utils.py +775 -265
  324. sky/serve/server/core.py +66 -711
  325. sky/serve/server/impl.py +1093 -0
  326. sky/serve/server/server.py +21 -18
  327. sky/serve/service.py +192 -89
  328. sky/serve/service_spec.py +144 -20
  329. sky/serve/spot_placer.py +3 -0
  330. sky/server/auth/__init__.py +0 -0
  331. sky/server/auth/authn.py +50 -0
  332. sky/server/auth/loopback.py +38 -0
  333. sky/server/auth/oauth2_proxy.py +202 -0
  334. sky/server/common.py +478 -182
  335. sky/server/config.py +85 -23
  336. sky/server/constants.py +44 -6
  337. sky/server/daemons.py +295 -0
  338. sky/server/html/token_page.html +185 -0
  339. sky/server/metrics.py +160 -0
  340. sky/server/middleware_utils.py +166 -0
  341. sky/server/requests/executor.py +558 -138
  342. sky/server/requests/payloads.py +364 -24
  343. sky/server/requests/preconditions.py +21 -17
  344. sky/server/requests/process.py +112 -29
  345. sky/server/requests/request_names.py +121 -0
  346. sky/server/requests/requests.py +822 -226
  347. sky/server/requests/serializers/decoders.py +82 -31
  348. sky/server/requests/serializers/encoders.py +140 -22
  349. sky/server/requests/threads.py +117 -0
  350. sky/server/rest.py +455 -0
  351. sky/server/server.py +1309 -285
  352. sky/server/state.py +20 -0
  353. sky/server/stream_utils.py +327 -61
  354. sky/server/uvicorn.py +217 -3
  355. sky/server/versions.py +270 -0
  356. sky/setup_files/MANIFEST.in +11 -1
  357. sky/setup_files/alembic.ini +160 -0
  358. sky/setup_files/dependencies.py +139 -31
  359. sky/setup_files/setup.py +44 -42
  360. sky/sky_logging.py +114 -7
  361. sky/skylet/attempt_skylet.py +106 -24
  362. sky/skylet/autostop_lib.py +129 -8
  363. sky/skylet/configs.py +29 -20
  364. sky/skylet/constants.py +216 -25
  365. sky/skylet/events.py +101 -21
  366. sky/skylet/job_lib.py +345 -164
  367. sky/skylet/log_lib.py +297 -18
  368. sky/skylet/log_lib.pyi +44 -1
  369. sky/skylet/providers/ibm/node_provider.py +12 -8
  370. sky/skylet/providers/ibm/vpc_provider.py +13 -12
  371. sky/skylet/ray_patches/__init__.py +17 -3
  372. sky/skylet/ray_patches/autoscaler.py.diff +18 -0
  373. sky/skylet/ray_patches/cli.py.diff +19 -0
  374. sky/skylet/ray_patches/command_runner.py.diff +17 -0
  375. sky/skylet/ray_patches/log_monitor.py.diff +20 -0
  376. sky/skylet/ray_patches/resource_demand_scheduler.py.diff +32 -0
  377. sky/skylet/ray_patches/updater.py.diff +18 -0
  378. sky/skylet/ray_patches/worker.py.diff +41 -0
  379. sky/skylet/runtime_utils.py +21 -0
  380. sky/skylet/services.py +568 -0
  381. sky/skylet/skylet.py +72 -4
  382. sky/skylet/subprocess_daemon.py +104 -29
  383. sky/skypilot_config.py +506 -99
  384. sky/ssh_node_pools/__init__.py +1 -0
  385. sky/ssh_node_pools/core.py +135 -0
  386. sky/ssh_node_pools/server.py +233 -0
  387. sky/task.py +685 -163
  388. sky/templates/aws-ray.yml.j2 +11 -3
  389. sky/templates/azure-ray.yml.j2 +2 -1
  390. sky/templates/cudo-ray.yml.j2 +1 -0
  391. sky/templates/do-ray.yml.j2 +2 -1
  392. sky/templates/fluidstack-ray.yml.j2 +1 -0
  393. sky/templates/gcp-ray.yml.j2 +62 -1
  394. sky/templates/hyperbolic-ray.yml.j2 +68 -0
  395. sky/templates/ibm-ray.yml.j2 +2 -1
  396. sky/templates/jobs-controller.yaml.j2 +27 -24
  397. sky/templates/kubernetes-loadbalancer.yml.j2 +2 -0
  398. sky/templates/kubernetes-ray.yml.j2 +611 -50
  399. sky/templates/lambda-ray.yml.j2 +2 -1
  400. sky/templates/nebius-ray.yml.j2 +34 -12
  401. sky/templates/oci-ray.yml.j2 +1 -0
  402. sky/templates/paperspace-ray.yml.j2 +2 -1
  403. sky/templates/primeintellect-ray.yml.j2 +72 -0
  404. sky/templates/runpod-ray.yml.j2 +10 -1
  405. sky/templates/scp-ray.yml.j2 +4 -50
  406. sky/templates/seeweb-ray.yml.j2 +171 -0
  407. sky/templates/shadeform-ray.yml.j2 +73 -0
  408. sky/templates/sky-serve-controller.yaml.j2 +22 -2
  409. sky/templates/vast-ray.yml.j2 +1 -0
  410. sky/templates/vsphere-ray.yml.j2 +1 -0
  411. sky/templates/websocket_proxy.py +212 -37
  412. sky/usage/usage_lib.py +31 -15
  413. sky/users/__init__.py +0 -0
  414. sky/users/model.conf +15 -0
  415. sky/users/permission.py +397 -0
  416. sky/users/rbac.py +121 -0
  417. sky/users/server.py +720 -0
  418. sky/users/token_service.py +218 -0
  419. sky/utils/accelerator_registry.py +35 -5
  420. sky/utils/admin_policy_utils.py +84 -38
  421. sky/utils/annotations.py +38 -5
  422. sky/utils/asyncio_utils.py +78 -0
  423. sky/utils/atomic.py +1 -1
  424. sky/utils/auth_utils.py +153 -0
  425. sky/utils/benchmark_utils.py +60 -0
  426. sky/utils/cli_utils/status_utils.py +159 -86
  427. sky/utils/cluster_utils.py +31 -9
  428. sky/utils/command_runner.py +354 -68
  429. sky/utils/command_runner.pyi +93 -3
  430. sky/utils/common.py +35 -8
  431. sky/utils/common_utils.py +314 -91
  432. sky/utils/config_utils.py +74 -5
  433. sky/utils/context.py +403 -0
  434. sky/utils/context_utils.py +242 -0
  435. sky/utils/controller_utils.py +383 -89
  436. sky/utils/dag_utils.py +31 -12
  437. sky/utils/db/__init__.py +0 -0
  438. sky/utils/db/db_utils.py +485 -0
  439. sky/utils/db/kv_cache.py +149 -0
  440. sky/utils/db/migration_utils.py +137 -0
  441. sky/utils/directory_utils.py +12 -0
  442. sky/utils/env_options.py +13 -0
  443. sky/utils/git.py +567 -0
  444. sky/utils/git_clone.sh +460 -0
  445. sky/utils/infra_utils.py +195 -0
  446. sky/utils/kubernetes/cleanup-tunnel.sh +62 -0
  447. sky/utils/kubernetes/config_map_utils.py +133 -0
  448. sky/utils/kubernetes/create_cluster.sh +15 -29
  449. sky/utils/kubernetes/delete_cluster.sh +10 -7
  450. sky/utils/kubernetes/deploy_ssh_node_pools.py +1177 -0
  451. sky/utils/kubernetes/exec_kubeconfig_converter.py +22 -31
  452. sky/utils/kubernetes/generate_kind_config.py +6 -66
  453. sky/utils/kubernetes/generate_kubeconfig.sh +4 -1
  454. sky/utils/kubernetes/gpu_labeler.py +18 -8
  455. sky/utils/kubernetes/k8s_gpu_labeler_job.yaml +2 -1
  456. sky/utils/kubernetes/k8s_gpu_labeler_setup.yaml +16 -16
  457. sky/utils/kubernetes/kubernetes_deploy_utils.py +284 -114
  458. sky/utils/kubernetes/rsync_helper.sh +11 -3
  459. sky/utils/kubernetes/ssh-tunnel.sh +379 -0
  460. sky/utils/kubernetes/ssh_utils.py +221 -0
  461. sky/utils/kubernetes_enums.py +8 -15
  462. sky/utils/lock_events.py +94 -0
  463. sky/utils/locks.py +416 -0
  464. sky/utils/log_utils.py +82 -107
  465. sky/utils/perf_utils.py +22 -0
  466. sky/utils/resource_checker.py +298 -0
  467. sky/utils/resources_utils.py +249 -32
  468. sky/utils/rich_utils.py +217 -39
  469. sky/utils/schemas.py +955 -160
  470. sky/utils/serialize_utils.py +16 -0
  471. sky/utils/status_lib.py +10 -0
  472. sky/utils/subprocess_utils.py +29 -15
  473. sky/utils/tempstore.py +70 -0
  474. sky/utils/thread_utils.py +91 -0
  475. sky/utils/timeline.py +26 -53
  476. sky/utils/ux_utils.py +84 -15
  477. sky/utils/validator.py +11 -1
  478. sky/utils/volume.py +165 -0
  479. sky/utils/yaml_utils.py +111 -0
  480. sky/volumes/__init__.py +13 -0
  481. sky/volumes/client/__init__.py +0 -0
  482. sky/volumes/client/sdk.py +150 -0
  483. sky/volumes/server/__init__.py +0 -0
  484. sky/volumes/server/core.py +270 -0
  485. sky/volumes/server/server.py +124 -0
  486. sky/volumes/volume.py +215 -0
  487. sky/workspaces/__init__.py +0 -0
  488. sky/workspaces/core.py +655 -0
  489. sky/workspaces/server.py +101 -0
  490. sky/workspaces/utils.py +56 -0
  491. sky_templates/README.md +3 -0
  492. sky_templates/__init__.py +3 -0
  493. sky_templates/ray/__init__.py +0 -0
  494. sky_templates/ray/start_cluster +183 -0
  495. sky_templates/ray/stop_cluster +75 -0
  496. skypilot_nightly-1.0.0.dev20251203.dist-info/METADATA +676 -0
  497. skypilot_nightly-1.0.0.dev20251203.dist-info/RECORD +611 -0
  498. {skypilot_nightly-1.0.0.dev20250502.dist-info → skypilot_nightly-1.0.0.dev20251203.dist-info}/WHEEL +1 -1
  499. skypilot_nightly-1.0.0.dev20251203.dist-info/top_level.txt +2 -0
  500. sky/benchmark/benchmark_state.py +0 -256
  501. sky/benchmark/benchmark_utils.py +0 -641
  502. sky/clouds/service_catalog/constants.py +0 -7
  503. sky/dashboard/out/_next/static/GWvVBSCS7FmUiVmjaL1a7/_buildManifest.js +0 -1
  504. sky/dashboard/out/_next/static/chunks/236-2db3ee3fba33dd9e.js +0 -6
  505. sky/dashboard/out/_next/static/chunks/312-c3c8845990db8ffc.js +0 -15
  506. sky/dashboard/out/_next/static/chunks/37-0a572fe0dbb89c4d.js +0 -6
  507. sky/dashboard/out/_next/static/chunks/678-206dddca808e6d16.js +0 -59
  508. sky/dashboard/out/_next/static/chunks/845-9e60713e0c441abc.js +0 -1
  509. sky/dashboard/out/_next/static/chunks/979-7bf73a4c7cea0f5c.js +0 -1
  510. sky/dashboard/out/_next/static/chunks/fd9d1056-2821b0f0cabcd8bd.js +0 -1
  511. sky/dashboard/out/_next/static/chunks/framework-87d061ee6ed71b28.js +0 -33
  512. sky/dashboard/out/_next/static/chunks/main-app-241eb28595532291.js +0 -1
  513. sky/dashboard/out/_next/static/chunks/main-e0e2335212e72357.js +0 -1
  514. sky/dashboard/out/_next/static/chunks/pages/_app-e6b013bc3f77ad60.js +0 -1
  515. sky/dashboard/out/_next/static/chunks/pages/_error-1be831200e60c5c0.js +0 -1
  516. sky/dashboard/out/_next/static/chunks/pages/clusters/[cluster]/[job]-6ac338bc2239cb45.js +0 -1
  517. sky/dashboard/out/_next/static/chunks/pages/clusters/[cluster]-f383db7389368ea7.js +0 -1
  518. sky/dashboard/out/_next/static/chunks/pages/clusters-a93b93e10b8b074e.js +0 -1
  519. sky/dashboard/out/_next/static/chunks/pages/index-f9f039532ca8cbc4.js +0 -1
  520. sky/dashboard/out/_next/static/chunks/pages/jobs/[job]-1c519e1afc523dc9.js +0 -1
  521. sky/dashboard/out/_next/static/chunks/pages/jobs-a75029b67aab6a2e.js +0 -1
  522. sky/dashboard/out/_next/static/chunks/webpack-830f59b8404e96b8.js +0 -1
  523. sky/dashboard/out/_next/static/css/c6933bbb2ce7f4dd.css +0 -3
  524. sky/jobs/dashboard/dashboard.py +0 -223
  525. sky/jobs/dashboard/static/favicon.ico +0 -0
  526. sky/jobs/dashboard/templates/index.html +0 -831
  527. sky/jobs/server/dashboard_utils.py +0 -69
  528. sky/skylet/providers/scp/__init__.py +0 -2
  529. sky/skylet/providers/scp/config.py +0 -149
  530. sky/skylet/providers/scp/node_provider.py +0 -578
  531. sky/templates/kubernetes-ssh-jump.yml.j2 +0 -94
  532. sky/utils/db_utils.py +0 -100
  533. sky/utils/kubernetes/deploy_remote_cluster.sh +0 -308
  534. sky/utils/kubernetes/ssh_jump_lifecycle_manager.py +0 -191
  535. skypilot_nightly-1.0.0.dev20250502.dist-info/METADATA +0 -361
  536. skypilot_nightly-1.0.0.dev20250502.dist-info/RECORD +0 -396
  537. skypilot_nightly-1.0.0.dev20250502.dist-info/top_level.txt +0 -1
  538. /sky/{clouds/service_catalog → catalog}/config.py +0 -0
  539. /sky/{benchmark → catalog/data_fetchers}/__init__.py +0 -0
  540. /sky/{clouds/service_catalog → catalog}/data_fetchers/fetch_azure.py +0 -0
  541. /sky/{clouds/service_catalog → catalog}/data_fetchers/fetch_fluidstack.py +0 -0
  542. /sky/{clouds/service_catalog → catalog}/data_fetchers/fetch_ibm.py +0 -0
  543. /sky/{clouds/service_catalog/data_fetchers → client/cli}/__init__.py +0 -0
  544. /sky/dashboard/out/_next/static/{GWvVBSCS7FmUiVmjaL1a7 → 96_E2yl3QAiIJGOYCkSpB}/_ssgManifest.js +0 -0
  545. {skypilot_nightly-1.0.0.dev20250502.dist-info → skypilot_nightly-1.0.0.dev20251203.dist-info}/entry_points.txt +0 -0
  546. {skypilot_nightly-1.0.0.dev20250502.dist-info → skypilot_nightly-1.0.0.dev20251203.dist-info}/licenses/LICENSE +0 -0
@@ -3,7 +3,6 @@
3
3
  This module contains a set of rest api functions accessing SCP Open-API.
4
4
  """
5
5
  import base64
6
- import datetime
7
6
  from functools import wraps
8
7
  import hashlib
9
8
  import hmac
@@ -171,29 +170,30 @@ class SCPClient:
171
170
  self.secret_key = self._credentials['secret_key']
172
171
  self.project_id = self._credentials['project_id']
173
172
  self.client_type = 'OpenApi'
174
- self.timestamp = ''
175
- self.signature = ''
176
-
177
- self.headers = {
178
- 'X-Cmp-AccessKey': f'{self.access_key}',
179
- 'X-Cmp-ClientType': f'{self.client_type}',
180
- 'X-Cmp-ProjectId': f'{self.project_id}',
181
- 'X-Cmp-Timestamp': f'{self.timestamp}',
182
- 'X-Cmp-Signature': f'{self.signature}'
173
+
174
+ def _signed_headers(self, method: str, url: str) -> dict:
175
+ timestamp = str(int(time.time() * 1000))
176
+ signature = self.get_signature(method=method,
177
+ url=url,
178
+ timestamp=timestamp)
179
+ return {
180
+ 'X-Cmp-AccessKey': self.access_key,
181
+ 'X-Cmp-ClientType': self.client_type,
182
+ 'X-Cmp-ProjectId': self.project_id,
183
+ 'X-Cmp-Timestamp': timestamp,
184
+ 'X-Cmp-Signature': signature,
183
185
  }
184
186
 
185
187
  def create_instance(self, instance_config):
186
188
  """Launch new instances."""
187
- url = f'{API_ENDPOINT}/virtual-server/v3/virtual-servers'
189
+ url = f'{API_ENDPOINT}/virtual-server/v4/virtual-servers'
188
190
  return self._post(url, instance_config)
189
191
 
190
192
  @_retry
191
193
  def _get(self, url, contents_key='contents'):
192
194
  method = 'GET'
193
- self.set_timestamp()
194
- self.set_signature(url=url, method=method)
195
-
196
- response = requests.get(url, headers=self.headers)
195
+ headers = self._signed_headers(method, url)
196
+ response = requests.get(url, headers=headers)
197
197
  raise_scp_error(response)
198
198
  if contents_key is not None:
199
199
  return response.json().get(contents_key, [])
@@ -203,135 +203,167 @@ class SCPClient:
203
203
  @_retry
204
204
  def _post(self, url, request_body):
205
205
  method = 'POST'
206
- self.set_timestamp()
207
- self.set_signature(url=url, method=method)
208
-
209
- response = requests.post(url, json=request_body, headers=self.headers)
210
-
206
+ headers = self._signed_headers(method, url)
207
+ response = requests.post(url, json=request_body, headers=headers)
211
208
  raise_scp_error(response)
212
209
  return response.json()
213
210
 
214
211
  @_retry
215
212
  def _delete(self, url, request_body=None):
216
213
  method = 'DELETE'
217
- self.set_timestamp()
218
- self.set_signature(url=url, method=method)
214
+ headers = self._signed_headers(method, url)
219
215
  if request_body:
220
- response = requests.delete(url,
221
- json=request_body,
222
- headers=self.headers)
223
-
216
+ response = requests.delete(url, json=request_body, headers=headers)
224
217
  else:
225
- response = requests.delete(url, headers=self.headers)
218
+ response = requests.delete(url, headers=headers)
226
219
  raise_scp_error(response)
227
220
  return response.json()
228
221
 
229
- def create_security_group(self, zone_id, vpc, sg_name):
222
+ def create_security_group(self, zone_id, vpc_id, sg_name):
230
223
  url = f'{API_ENDPOINT}/security-group/v3/security-groups'
231
224
  request_body = {
232
225
  'loggable': False,
233
226
  'securityGroupName': sg_name,
234
227
  'serviceZoneId': zone_id,
235
- 'vpcId': vpc,
236
- 'securityGroupDescription': 'skypilot sg'
237
- }
238
- return self._post(url, request_body)
239
-
240
- def add_security_group_in_rule(self, sg_id):
241
- url = f'{API_ENDPOINT}/security-group/v2/security-groups/{sg_id}/rules'
242
- request_body = {
243
- 'ruleDirection': 'IN',
244
- 'services': [{
245
- 'serviceType': 'TCP',
246
- 'serviceValue': '22'
247
- }],
248
- 'sourceIpAddresses': ['0.0.0.0/0'],
249
- 'ruleDescription': 'skypilot ssh rule'
250
- }
251
- return self._post(url, request_body)
252
-
253
- def add_security_group_out_rule(self, sg_id):
254
- url = f'{API_ENDPOINT}/security-group/v2/security-groups/{sg_id}/rules'
255
- request_body = {
256
- 'ruleDirection': 'OUT',
257
- 'services': [{
258
- 'serviceType': 'TCP',
259
- 'serviceValue': '21'
260
- }, {
261
- 'serviceType': 'TCP',
262
- 'serviceValue': '22'
263
- }, {
264
- 'serviceType': 'TCP',
265
- 'serviceValue': '80'
266
- }, {
267
- 'serviceType': 'TCP',
268
- 'serviceValue': '443'
269
- }],
270
- 'destinationIpAddresses': ['0.0.0.0/0'],
271
- 'ruleDescription': 'skypilot out rule'
272
- }
273
- return self._post(url, request_body)
274
-
275
- def add_firewall_inbound_rule(self, firewall_id, internal_ip):
276
- url = f'{API_ENDPOINT}/firewall/v2/firewalls/{firewall_id}/rules'
277
- request_body = {
278
- 'sourceIpAddresses': ['0.0.0.0/0'],
279
- 'destinationIpAddresses': [internal_ip],
280
- 'services': [{
281
- 'serviceType': 'TCP',
282
- 'serviceValue': '22'
283
- }],
284
- 'ruleDirection': 'IN',
285
- 'ruleAction': 'ALLOW',
286
- 'isRuleEnabled': True,
287
- 'ruleLocationType': 'FIRST',
288
- 'ruleDescription': 'description'
228
+ 'vpcId': vpc_id,
229
+ 'securityGroupDescription': 'sky security group'
289
230
  }
290
231
  return self._post(url, request_body)
291
232
 
292
- def add_firewall_outbound_rule(self, firewall_id, internal_ip):
293
- url = f'{API_ENDPOINT}/firewall/v2/firewalls/{firewall_id}/rules'
294
- request_body = {
295
- 'sourceIpAddresses': [internal_ip],
296
- 'destinationIpAddresses': ['0.0.0.0/0'],
297
- 'services': [{
298
- 'serviceType': 'TCP',
299
- 'serviceValue': '21'
300
- }, {
301
- 'serviceType': 'TCP',
302
- 'serviceValue': '22'
303
- }, {
304
- 'serviceType': 'TCP',
305
- 'serviceValue': '80'
306
- }, {
307
- 'serviceType': 'TCP',
308
- 'serviceValue': '443'
309
- }],
310
- 'ruleDirection': 'OUT',
311
- 'ruleAction': 'ALLOW',
312
- 'isRuleEnabled': True,
313
- 'ruleLocationType': 'FIRST',
314
- 'ruleDescription': 'description'
315
- }
316
- return self._post(url, request_body)
233
+ def _security_group_rule_not_exist(self, sg_id, direction, ports):
234
+ response = self.get_security_group_rules(sg_id)
235
+ rules = []
236
+ for rule in response:
237
+ rule_direction = rule['ruleDirection']
238
+ if rule_direction == direction:
239
+ rules.append(rule)
240
+ for rule in rules:
241
+ port_list = ','.join(rule['tcpServices'])
242
+ port = ','.join(ports)
243
+ if port == port_list:
244
+ return False
245
+ return True
246
+
247
+ def add_security_group_rule(self, sg_id, direction,
248
+ ports: Optional[List[str]],
249
+ cnt: Optional[int]) -> None:
250
+ if ports is None:
251
+ if direction == 'IN':
252
+ if cnt == 1:
253
+ ports = ['22']
254
+ else:
255
+ ports = ['22', '6380', '8076', '10001', '11001-11200']
256
+ else:
257
+ if cnt == 1:
258
+ ports = ['21', '22', '80', '443']
259
+ else:
260
+ ports = [
261
+ '21', '22', '80', '443', '6380', '8076', '10001',
262
+ '11001-11200'
263
+ ]
264
+ services = []
265
+ for port in ports:
266
+ services.append({'serviceType': 'TCP', 'serviceValue': port})
267
+ if self._security_group_rule_not_exist(sg_id, direction, ports):
268
+ url = f'{API_ENDPOINT}/security-group/v2/security-groups/{sg_id}/rules' # pylint: disable=line-too-long
269
+ if direction == 'IN':
270
+ target_address = 'sourceIpAddresses'
271
+ else:
272
+ target_address = 'destinationIpAddresses'
273
+ request_body = {
274
+ 'ruleDirection': direction,
275
+ 'services': services,
276
+ target_address: ['0.0.0.0/0'],
277
+ 'ruleDescription': 'sky security group rule'
278
+ }
279
+ self._post(url, request_body)
280
+ else:
281
+ return None
282
+
283
+ def _firewall_rule_not_exist(self, firewall_id, internal_ip, direction,
284
+ ports):
285
+ response = self.get_firewall_rules(firewall_id)
286
+ rules = []
287
+ for rule in response:
288
+ if direction == 'IN':
289
+ if internal_ip == rule['destinationIpAddresses'][0]:
290
+ rules.append(rule)
291
+ else:
292
+ if internal_ip == rule['sourceIpAddresses'][0]:
293
+ rules.append(rule)
294
+ for rule in rules:
295
+ port_list = ','.join(rule['tcpServices'])
296
+ port = ','.join(ports)
297
+ if port == port_list:
298
+ return False
299
+ return True
300
+
301
+ def add_firewall_rule(self, firewall_id, internal_ip, direction,
302
+ ports: Optional[List[str]], cnt: Optional[int]):
303
+ if ports is None:
304
+ if direction == 'IN':
305
+ if cnt == 1:
306
+ ports = ['22']
307
+ else:
308
+ ports = ['22', '6380', '8076', '10001', '11001-11200']
309
+ else:
310
+ if cnt == 1:
311
+ ports = ['21', '22', '80', '443']
312
+ else:
313
+ ports = [
314
+ '21', '22', '80', '443', '6380', '8076', '10001',
315
+ '11001-11200'
316
+ ]
317
+ services = []
318
+ for port in ports:
319
+ services.append({'serviceType': 'TCP', 'serviceValue': port})
320
+ if self._firewall_rule_not_exist(firewall_id, internal_ip, direction,
321
+ ports):
322
+ url = f'{API_ENDPOINT}/firewall/v2/firewalls/{firewall_id}/rules'
323
+ if direction == 'IN':
324
+ source_ip = '0.0.0.0/0'
325
+ destination_ip = internal_ip
326
+ else:
327
+ source_ip = internal_ip
328
+ destination_ip = '0.0.0.0/0'
329
+ request_body = {
330
+ 'sourceIpAddresses': [source_ip],
331
+ 'destinationIpAddresses': [destination_ip],
332
+ 'services': services,
333
+ 'ruleDirection': direction,
334
+ 'ruleAction': 'ALLOW',
335
+ 'isRuleEnabled': True,
336
+ 'ruleLocationType': 'FIRST',
337
+ 'ruleDescription': 'sky firewall rule'
338
+ }
339
+ return self._post(url, request_body)
340
+ else:
341
+ return None
317
342
 
318
- def terminate_instance(self, vm_id):
319
- url = f'{API_ENDPOINT}/virtual-server/v2/virtual-servers/{vm_id}'
343
+ def terminate_instance(self, instance_id):
344
+ url = f'{API_ENDPOINT}/virtual-server/v2/virtual-servers/{instance_id}'
320
345
  return self._delete(url)
321
346
 
322
- def list_instances(self) -> List[dict]:
347
+ def get_instances(self) -> List[dict]:
323
348
  """List existing instances."""
324
349
  url = f'{API_ENDPOINT}/virtual-server/v2/virtual-servers'
325
350
  return self._get(url)
326
351
 
327
- def list_catalog(self) -> Dict[str, Any]:
352
+ def get_catalog(self) -> Dict[str, Any]:
328
353
  """List offered instances and their availability."""
329
- response = requests.get(f'{API_ENDPOINT}/instance-types',
330
- headers=self.headers)
354
+ url = f'{API_ENDPOINT}/instance-types'
355
+ headers = self._signed_headers('GET', url)
356
+ response = requests.get(url, headers=headers)
331
357
  raise_scp_error(response)
332
358
  return response.json().get('data', [])
333
359
 
334
- def get_signature(self, method: str, url: str) -> str:
360
+ def get_signature(self,
361
+ method: str,
362
+ url: str,
363
+ timestamp: Optional[str] = None) -> str:
364
+ if timestamp is None:
365
+ timestamp = str(int(time.time() * 1000))
366
+
335
367
  url_info = parse.urlsplit(url)
336
368
  url = (f'{url_info.scheme}://{url_info.netloc}'
337
369
  f'{parse.quote(url_info.path)}')
@@ -341,7 +373,7 @@ class SCPClient:
341
373
  parse.parse_qs(url_info.query).items()))
342
374
  url = f'{url}?{parse.urlencode(enc_params)}'
343
375
 
344
- message = method + url + self.timestamp \
376
+ message = method + url + timestamp \
345
377
  + self.access_key + self.project_id + self.client_type
346
378
  message = bytes(message, 'utf-8')
347
379
  secret = bytes(self.secret_key, 'utf-8')
@@ -352,99 +384,131 @@ class SCPClient:
352
384
 
353
385
  return str(signature)
354
386
 
355
- def set_timestamp(self) -> None:
356
- self.timestamp = str(
357
- int(
358
- round(
359
- datetime.datetime.timestamp(datetime.datetime.now() -
360
- datetime.timedelta(minutes=1)) *
361
- 1000)))
362
- self.headers['X-Cmp-Timestamp'] = self.timestamp
363
-
364
- def set_signature(self, method: str, url: str) -> None:
365
-
366
- self.signature = self.get_signature(url=url, method=method)
367
- self.headers['X-Cmp-Signature'] = self.signature
368
-
369
- def list_nic_details(self, virtual_server_id) -> List[dict]:
370
- """List existing instances."""
371
- url = f'{API_ENDPOINT}/virtual-server/v2/virtual-servers/{virtual_server_id}/nics' # pylint: disable=line-too-long
387
+ def get_nic(self, instance_id) -> List[dict]:
388
+ url = f'{API_ENDPOINT}/virtual-server/v2/virtual-servers/{instance_id}/nics' # pylint: disable=line-too-long
372
389
  return self._get(url)
373
390
 
374
- def get_external_ip(self, virtual_server_id, ip):
375
- nic_details_list = self.list_nic_details(
376
- virtual_server_id=virtual_server_id)
377
- for nic_details in nic_details_list:
378
- if (nic_details['ip'] == ip and
379
- nic_details['subnetType'] == 'PUBLIC'):
380
- return nic_details['natIp']
391
+ def get_external_ip(self, instance_id, ip):
392
+ nics = self.get_nic(instance_id=instance_id)
393
+ for nic in nics:
394
+ if (nic['ip'] == ip and nic['subnetType'] == 'PUBLIC'):
395
+ return nic['natIp']
381
396
  return None
382
397
 
383
- def list_zones(self) -> List[dict]:
398
+ def get_zones(self) -> List[dict]:
384
399
  url = f'{API_ENDPOINT}/project/v3/projects/{self.project_id}/zones'
385
400
  return self._get(url)
386
401
 
387
- def list_products(self, service_zone_id) -> List[dict]:
388
- url = f'{API_ENDPOINT}/product/v2/zones/{service_zone_id}/products'
389
- return self._get(url)
390
-
391
- def list_product_groups(self, service_zone_id) -> List[dict]:
392
- url = f'{API_ENDPOINT}/product/v2/zones/{service_zone_id}/product-groups' # pylint: disable=line-too-long
393
- return self._get(url)
394
-
395
- def list_vpcs(self, service_zone_id) -> List[dict]:
402
+ def get_vpcs(self, service_zone_id) -> List[dict]:
396
403
  url = f'{API_ENDPOINT}/vpc/v2/vpcs?serviceZoneId={service_zone_id}'
397
404
  return self._get(url)
398
405
 
399
- def list_subnets(self) -> List[dict]:
406
+ def get_subnets(self) -> List[dict]:
400
407
  url = f'{API_ENDPOINT}/subnet/v2/subnets?subnetTypes=PUBLIC'
401
408
  return self._get(url)
402
409
 
403
- def del_security_group(self, sg_id):
410
+ def delete_security_group(self, sg_id):
404
411
  url = f'{API_ENDPOINT}/security-group/v2/security-groups/{sg_id}'
405
412
  return self._delete(url)
406
413
 
407
- def del_firwall_rules(self, firewall_id, rule_id_list):
414
+ def delete_firewall_rule(self, firewall_id, rule_ids):
408
415
  url = f'{API_ENDPOINT}/firewall/v2/firewalls/{firewall_id}/rules'
409
- request_body = {'ruleDeletionType': 'PARTIAL', 'ruleIds': rule_id_list}
416
+ request_body = {'ruleDeletionType': 'PARTIAL', 'ruleIds': rule_ids}
410
417
  return self._delete(url, request_body=request_body)
411
418
 
412
- def list_security_groups(self, vpc_id=None, sg_name=None):
419
+ def get_security_groups(self, vpc_id=None, sg_name=None):
413
420
  url = f'{API_ENDPOINT}/security-group/v2/security-groups'
414
421
  parameter = []
415
422
  if vpc_id is not None:
416
423
  parameter.append('vpcId=' + vpc_id)
417
424
  if sg_name is not None:
418
425
  parameter.append('securityGroupName=' + sg_name)
419
- if parameter:
426
+ if len(parameter) > 0:
420
427
  url = url + '?' + '&'.join(parameter)
421
428
  return self._get(url)
422
429
 
423
- def list_igw(self):
430
+ def get_internet_gateway(self):
424
431
  url = f'{API_ENDPOINT}/internet-gateway/v2/internet-gateways'
425
432
  return self._get(url)
426
433
 
427
- def get_vm_info(self, vm_id):
428
- url = f'{API_ENDPOINT}/virtual-server/v3/virtual-servers/{vm_id}'
429
- return self._get(url, contents_key=None)
430
-
431
- def get_firewal_rule_info(self, firewall_id, rule_id):
434
+ def get_firewall_rule_info(self, firewall_id, rule_id):
432
435
  url = f'{API_ENDPOINT}/firewall/v2/firewalls/{firewall_id}/rules/{rule_id}' # pylint: disable=line-too-long
433
436
  return self._get(url, contents_key=None)
434
437
 
435
- def list_firwalls(self):
438
+ def get_firewalls(self):
436
439
  url = f'{API_ENDPOINT}/firewall/v2/firewalls'
437
440
  return self._get(url)
438
441
 
439
- def list_service_zone_names(self):
442
+ def get_service_zone_names(self):
440
443
  url = f'{API_ENDPOINT}/project/v3/projects/{self.project_id}/zones'
441
444
  zone_contents = self._get(url)
442
445
  return [content['serviceZoneName'] for content in zone_contents]
443
446
 
444
- def start_instance(self, vm_id):
445
- url = f'{API_ENDPOINT}/virtual-server/v2/virtual-servers/{vm_id}/start'
447
+ def start_instance(self, instance_id):
448
+ url = f'{API_ENDPOINT}/virtual-server/v2/virtual-servers/{instance_id}/start' # pylint: disable=line-too-long
446
449
  return self._post(url=url, request_body={})
447
450
 
448
- def stop_instance(self, vm_id):
449
- url = f'{API_ENDPOINT}/virtual-server/v2/virtual-servers/{vm_id}/stop'
451
+ def stop_instance(self, instance_id):
452
+ url = f'{API_ENDPOINT}/virtual-server/v2/virtual-servers/{instance_id}/stop' # pylint: disable=line-too-long
450
453
  return self._post(url=url, request_body={})
454
+
455
+ def get_security_group_rules(self, sg_id):
456
+ url = f'{API_ENDPOINT}/security-group/v2/security-groups/{sg_id}/rules'
457
+ return self._get(url)
458
+
459
+ def get_firewall_rules(self, firewall_id):
460
+ url = f'{API_ENDPOINT}/firewall/v2/firewalls/{firewall_id}/rules'
461
+ return self._get(url)
462
+
463
+ def get_instance_info(self, instance_id):
464
+ url = f'{API_ENDPOINT}/virtual-server/v3/virtual-servers/{instance_id}'
465
+ return self._get(url=url, contents_key=None)
466
+
467
+ def create_vpc(self, zone_id):
468
+ vpc_name = 'skyvpc' + zone_id[5:10]
469
+ request_body = {
470
+ 'serviceZoneId': zone_id,
471
+ 'vpcName': vpc_name,
472
+ 'vpcDescription': 'sky vpc'
473
+ }
474
+ url = f'{API_ENDPOINT}/vpc/v3/vpcs'
475
+ return self._post(url, request_body)
476
+
477
+ def create_subnet(self, vpc_id, zone_id):
478
+ subnet_name = 'skysubnet' + zone_id[5:10]
479
+ request_body = {
480
+ 'subnetCidrBlock': '192.168.0.0/24',
481
+ 'subnetName': subnet_name,
482
+ 'subnetType': 'PUBLIC',
483
+ 'vpcId': vpc_id,
484
+ 'subnetDescription': 'sky subnet'
485
+ }
486
+ url = f'{API_ENDPOINT}/subnet/v2/subnets'
487
+ return self._post(url, request_body)
488
+
489
+ def create_internet_gateway(self, vpc_id):
490
+ request_body = {
491
+ 'firewallEnabled': True,
492
+ 'firewallLoggable': False,
493
+ 'internetGatewayType': 'SHARED',
494
+ 'vpcId': vpc_id,
495
+ 'internetGatewayDescription': 'sky internet gateway'
496
+ }
497
+ url = f'{API_ENDPOINT}/internet-gateway/v4/internet-gateways'
498
+ return self._post(url, request_body)
499
+
500
+ def get_vpc_info(self, vpc_id):
501
+ url = f'{API_ENDPOINT}/vpc/v2/vpcs/{vpc_id}'
502
+ return self._get(url=url, contents_key=None)
503
+
504
+ def get_subnet_info(self, subnet_id):
505
+ url = f'{API_ENDPOINT}/subnet/v2/subnets/{subnet_id}'
506
+ return self._get(url=url, contents_key=None)
507
+
508
+ def get_internet_gateway_info(self, internet_gateway_id):
509
+ url = f'{API_ENDPOINT}/internet-gateway/v2/internet-gateways/{internet_gateway_id}' # pylint: disable=line-too-long
510
+ return self._get(url=url, contents_key=None)
511
+
512
+ def get_key_pairs(self):
513
+ url = f'{API_ENDPOINT}/key-pair/v1/key-pairs'
514
+ return self._get(url=url, contents_key=None)