anyscale 0.26.51__py3-none-any.whl → 0.26.53__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 (75) hide show
  1. anyscale/_private/anyscale_client/README.md +1 -1
  2. anyscale/_private/anyscale_client/anyscale_client.py +178 -46
  3. anyscale/_private/anyscale_client/common.py +61 -2
  4. anyscale/_private/anyscale_client/fake_anyscale_client.py +145 -8
  5. anyscale/_private/docgen/__main__.py +42 -31
  6. anyscale/_private/docgen/generator.py +63 -28
  7. anyscale/_private/docgen/models.md +4 -2
  8. anyscale/_private/sdk/__init__.py +124 -1
  9. anyscale/_private/workload/workload_config.py +4 -6
  10. anyscale/_private/workload/workload_sdk.py +105 -12
  11. anyscale/client/README.md +13 -11
  12. anyscale/client/openapi_client/__init__.py +3 -3
  13. anyscale/client/openapi_client/api/default_api.py +512 -316
  14. anyscale/client/openapi_client/models/__init__.py +3 -3
  15. anyscale/client/openapi_client/models/aws_config.py +2 -2
  16. anyscale/client/openapi_client/models/baseimagesenum.py +158 -1
  17. anyscale/client/openapi_client/models/cloud_data_bucket_presigned_url_request.py +31 -3
  18. anyscale/client/openapi_client/models/cloud_deployment.py +37 -36
  19. anyscale/client/openapi_client/models/cloud_resource.py +59 -3
  20. anyscale/client/openapi_client/models/cloud_resource_gcp.py +59 -3
  21. anyscale/client/openapi_client/models/create_cloud_resource.py +59 -3
  22. anyscale/client/openapi_client/models/create_cloud_resource_gcp.py +59 -3
  23. anyscale/client/openapi_client/models/create_resource_notification.py +31 -3
  24. anyscale/client/openapi_client/models/{decorated_cloud_deployment.py → decorated_cloud_resource.py} +124 -96
  25. anyscale/client/openapi_client/models/{clouddeployment_list_response.py → decoratedcloudresource_list_response.py} +15 -15
  26. anyscale/client/openapi_client/models/{decoratedclouddeployment_response.py → decoratedcloudresource_response.py} +11 -11
  27. anyscale/client/openapi_client/models/file_storage.py +4 -4
  28. anyscale/client/openapi_client/models/gcp_config.py +2 -2
  29. anyscale/client/openapi_client/models/ha_job_error_types.py +9 -2
  30. anyscale/client/openapi_client/models/object_storage.py +4 -4
  31. anyscale/client/openapi_client/models/ray_runtime_env_config.py +57 -1
  32. anyscale/client/openapi_client/models/resource_alert_event_type.py +2 -1
  33. anyscale/client/openapi_client/models/resource_notification.py +29 -1
  34. anyscale/client/openapi_client/models/supportedbaseimagesenum.py +155 -1
  35. anyscale/client/openapi_client/models/workload_info.py +31 -3
  36. anyscale/client/openapi_client/models/workload_state_info.py +29 -1
  37. anyscale/cloud/models.py +40 -43
  38. anyscale/commands/cloud_commands.py +93 -88
  39. anyscale/commands/command_examples.py +37 -49
  40. anyscale/commands/exec_commands.py +12 -1
  41. anyscale/commands/list_commands.py +42 -12
  42. anyscale/commands/project_commands.py +399 -115
  43. anyscale/commands/schedule_commands.py +22 -11
  44. anyscale/commands/service_commands.py +11 -6
  45. anyscale/commands/util.py +94 -1
  46. anyscale/commands/workspace_commands.py +92 -38
  47. anyscale/compute_config/__init__.py +1 -1
  48. anyscale/compute_config/_private/compute_config_sdk.py +8 -11
  49. anyscale/compute_config/commands.py +3 -3
  50. anyscale/compute_config/models.py +30 -30
  51. anyscale/controllers/cloud_controller.py +361 -360
  52. anyscale/controllers/kubernetes_verifier.py +1 -1
  53. anyscale/job/_private/job_sdk.py +41 -23
  54. anyscale/job/models.py +1 -1
  55. anyscale/project/__init__.py +101 -1
  56. anyscale/project/_private/project_sdk.py +90 -2
  57. anyscale/project/commands.py +188 -1
  58. anyscale/project/models.py +198 -2
  59. anyscale/sdk/anyscale_client/models/baseimagesenum.py +158 -1
  60. anyscale/sdk/anyscale_client/models/ray_runtime_env_config.py +57 -1
  61. anyscale/sdk/anyscale_client/models/supportedbaseimagesenum.py +155 -1
  62. anyscale/service/_private/service_sdk.py +2 -1
  63. anyscale/shared_anyscale_utils/latest_ray_version.py +1 -1
  64. anyscale/util.py +3 -0
  65. anyscale/utils/runtime_env.py +3 -1
  66. anyscale/version.py +1 -1
  67. anyscale/workspace/commands.py +114 -23
  68. anyscale/workspace/models.py +3 -5
  69. {anyscale-0.26.51.dist-info → anyscale-0.26.53.dist-info}/METADATA +1 -1
  70. {anyscale-0.26.51.dist-info → anyscale-0.26.53.dist-info}/RECORD +75 -75
  71. {anyscale-0.26.51.dist-info → anyscale-0.26.53.dist-info}/WHEEL +0 -0
  72. {anyscale-0.26.51.dist-info → anyscale-0.26.53.dist-info}/entry_points.txt +0 -0
  73. {anyscale-0.26.51.dist-info → anyscale-0.26.53.dist-info}/licenses/LICENSE +0 -0
  74. {anyscale-0.26.51.dist-info → anyscale-0.26.53.dist-info}/licenses/NOTICE +0 -0
  75. {anyscale-0.26.51.dist-info → anyscale-0.26.53.dist-info}/top_level.txt +0 -0
anyscale/cloud/models.py CHANGED
@@ -222,15 +222,6 @@ cloud = Cloud(
222
222
  return is_aggregated_logs_enabled
223
223
 
224
224
 
225
- ################################################################################
226
- # NOTE: The models below are copied from the OpenAPI CloudDeployment model, which
227
- # is what is used in the CLI. They are only defined here so that they appear in
228
- # the generated docs, to provide users with examples of the expected
229
- # CloudDeployment YAML format. There is no SDK support for Cloud Deployments,
230
- # nor is there SDK support for creating/updating/deleting Clouds.
231
- ################################################################################
232
-
233
-
234
225
  class NetworkingMode(ModelEnum):
235
226
  PUBLIC = "PUBLIC"
236
227
  PRIVATE = "PRIVATE"
@@ -275,13 +266,13 @@ object_storage:
275
266
  bucket_name: Optional[str] = field(
276
267
  default=None,
277
268
  metadata={
278
- "docstring": "The cloud storage bucket name, prefixed with the storage scheme (s3://bucket-name, gs://bucket-name, or azure://bucket-name)."
269
+ "docstring": "The cloud storage bucket name, prefixed with the storage scheme (s3://bucket-name, gs://bucket-name, or abfss://bucket-name@account.dfs.core.windows.net)."
279
270
  },
280
271
  )
281
272
  region: Optional[str] = field(
282
273
  default=None,
283
274
  metadata={
284
- "docstring": "The region for the cloud storage bucket. Defaults to the region of the deployment."
275
+ "docstring": "The region for the cloud storage bucket. Defaults to the region of the cloud resource."
285
276
  },
286
277
  )
287
278
  endpoint: Optional[str] = field(
@@ -321,13 +312,13 @@ file_storage:
321
312
  persistent_volume_claim: Optional[str] = field(
322
313
  default=None,
323
314
  metadata={
324
- "docstring": "For Kubernetes deployments, the name of the persistent volume claim used to mount shared storage into pods."
315
+ "docstring": "For Kubernetes resources, the name of the persistent volume claim used to mount shared storage into pods."
325
316
  },
326
317
  )
327
318
  csi_ephemeral_volume_driver: Optional[str] = field(
328
319
  default=None,
329
320
  metadata={
330
- "docstring": "For Kubernetes deployments, the CSI ephemeral volume driver used to mount shared storage into pods."
321
+ "docstring": "For Kubernetes resources, the CSI ephemeral volume driver used to mount shared storage into pods."
331
322
  },
332
323
  )
333
324
 
@@ -390,7 +381,7 @@ aws_config:
390
381
  cloudformation_id: Optional[str] = field(
391
382
  default=None,
392
383
  metadata={
393
- "docstring": "The CloudFormation stack ID, for deployments with Anyscale-managed resources."
384
+ "docstring": "The CloudFormation stack ID, for Anyscale-managed resources."
394
385
  },
395
386
  )
396
387
 
@@ -452,7 +443,7 @@ gcp_config:
452
443
  deployment_manager_id: Optional[str] = field(
453
444
  default=None,
454
445
  metadata={
455
- "docstring": "The deployment manager deployment ID, for deployments with Anyscale-managed resources."
446
+ "docstring": "The deployment manager deployment ID, for Anyscale-managed resources."
456
447
  },
457
448
  )
458
449
 
@@ -483,41 +474,48 @@ kubernetes_config:
483
474
  )
484
475
 
485
476
 
477
+ ################################################################################
478
+ # NOTE: The CloudResource model below is copied from the OpenAPI CloudDeployment
479
+ # model, which is what is actually used in the CLI. It is only defined here so
480
+ # that it appears in the generated docs, to provide users with examples of the
481
+ # expected YAML format. There is no CloudResource SDK support, so the name of
482
+ # this model should not actually matter. (There is also no Cloud SDK support.)
483
+ ################################################################################
486
484
  @dataclass(frozen=True)
487
- class CloudDeployment(ModelBase):
488
- """Cloud deployment configuration."""
485
+ class CloudResource(ModelBase):
486
+ """Cloud resource configuration."""
489
487
 
490
488
  __skip_py_example__ = True
491
489
 
492
490
  __doc_yaml_example__ = """\
493
- cloud_deployment:
494
- cloud_deployment_id: cldrsrc_12345678901234567890123456
495
- name: my-cloud-deployment
496
- provider: AWS
497
- compute_stack: VM
498
- region: us-west-2
499
- networking_mode: PUBLIC
500
- object_storage:
501
- bucket_name: s3://my-bucket
502
- file_storage:
503
- file_storage_id: fs-12345678901234567
504
- aws_config:
505
- vpc_id: vpc-12345678901234567
506
- subnet_ids:
507
- - subnet-11111111111111111
508
- - subnet-22222222222222222
509
- security_group_ids:
510
- - sg-12345678901234567
511
- anyscale_iam_role_id: arn:aws:iam::123456789012:role/anyscale-iam-role
512
- cluster_iam_role_id: arn:aws:iam::123456789012:role/cluster-node-role
513
- memorydb_cluster_name: my-memorydb-cluster
491
+ cloud_resource_id: cldrsrc_12345678901234567890123456
492
+ name: my-cloud-resource
493
+ provider: AWS
494
+ compute_stack: VM
495
+ region: us-west-2
496
+ networking_mode: PUBLIC
497
+ object_storage:
498
+ bucket_name: s3://my-bucket
499
+ file_storage:
500
+ file_storage_id: fs-12345678901234567
501
+ aws_config:
502
+ vpc_id: vpc-12345678901234567
503
+ subnet_ids:
504
+ - subnet-11111111111111111
505
+ - subnet-22222222222222222
506
+ security_group_ids:
507
+ - sg-12345678901234567
508
+ anyscale_iam_role_id: arn:aws:iam::123456789012:role/anyscale-iam-role
509
+ cluster_iam_role_id: arn:aws:iam::123456789012:role/cluster-node-role
510
+ memorydb_cluster_name: my-memorydb-cluster
514
511
  """
515
512
 
516
- cloud_deployment_id: Optional[str] = field(
517
- default=None, metadata={"docstring": "Unique identifier for this deployment."},
513
+ cloud_resource_id: Optional[str] = field(
514
+ default=None,
515
+ metadata={"docstring": "Unique identifier for this cloud resource."},
518
516
  )
519
517
  name: Optional[str] = field(
520
- default=None, metadata={"docstring": "The name of this deployment."},
518
+ default=None, metadata={"docstring": "The name of this cloud resource."},
521
519
  )
522
520
  provider: Union[CloudProvider, str] = field(
523
521
  default=CloudProvider.UNKNOWN,
@@ -528,8 +526,7 @@ cloud_deployment:
528
526
  metadata={"docstring": "The compute stack (VM or K8S)."},
529
527
  )
530
528
  region: Optional[str] = field(
531
- default=None,
532
- metadata={"docstring": "The region for the deployment (e.g., us-west-2)."},
529
+ default=None, metadata={"docstring": "The region (e.g., us-west-2)."},
533
530
  )
534
531
  networking_mode: Optional[NetworkingMode] = field(
535
532
  default=None,
@@ -244,8 +244,8 @@ def list_cloud(name: Optional[str], cloud_id: Optional[str], max_items: int,) ->
244
244
  )
245
245
 
246
246
 
247
- @cloud_cli.group("deployment", help="Manage the configuration for a cloud deployment.")
248
- def cloud_deployment_group() -> None:
247
+ @cloud_cli.group("resource", help="Manage the configuration for a cloud resource.")
248
+ def cloud_resource_group() -> None:
249
249
  pass
250
250
 
251
251
 
@@ -254,138 +254,74 @@ def cloud_config_group() -> None:
254
254
  pass
255
255
 
256
256
 
257
- @cloud_deployment_group.command(
257
+ @cloud_resource_group.command(
258
258
  name="create",
259
- help="Create a new cloud deployment in an existing cloud.",
259
+ help="Create a new cloud resource in an existing cloud.",
260
260
  cls=AnyscaleCommand,
261
- example=command_examples.CLOUD_DEPLOYMENT_CREATE_EXAMPLE,
261
+ example=command_examples.CLOUD_RESOURCE_CREATE_EXAMPLE,
262
262
  is_alpha=True,
263
263
  )
264
264
  @click.option(
265
265
  "--cloud",
266
- help="The name of the cloud to create the new deployment in.",
267
- type=str,
268
- required=True,
269
- )
270
- @click.option(
271
- "--file", "-f", help="YAML file containing the deployment spec.", required=True,
272
- )
273
- @click.option(
274
- "--skip-verification",
275
- is_flag=True,
276
- default=False,
277
- help="Skip cloud deployment verification.",
278
- )
279
- @click.option(
280
- "--yes", "-y", is_flag=True, default=False, help="Skip asking for confirmation."
281
- )
282
- def cloud_deployment_create(
283
- cloud: str, file: str, skip_verification: bool, yes: bool,
284
- ) -> None:
285
- try:
286
- CloudController().create_cloud_deployment(cloud, file, skip_verification, yes)
287
- except click.ClickException as e:
288
- print(e)
289
-
290
-
291
- @cloud_deployment_group.command(
292
- name="get",
293
- help="Get a cloud deployment for a cloud.",
294
- cls=AnyscaleCommand,
295
- example=command_examples.CLOUD_DEPLOYMENT_GET_EXAMPLE,
296
- is_alpha=True,
297
- )
298
- @click.option(
299
- "--cloud",
300
- help="The name of the cloud that the cloud deployment belongs to.",
301
- type=str,
302
- required=True,
303
- )
304
- @click.option(
305
- "--deployment",
306
- help="The name of the cloud deployment. If not provided, the primary cloud deployment will be returned.",
307
- type=str,
308
- required=False,
309
- )
310
- def cloud_deployment_get(cloud: str, deployment: Optional[str]) -> None:
311
- try:
312
- result = CloudController().get_cloud_deployment_dict_by_name(cloud, deployment)
313
- print(yaml.dump(result, sort_keys=False))
314
- except click.ClickException as e:
315
- print(e)
316
-
317
-
318
- @cloud_deployment_group.command(
319
- name="update",
320
- help="Update a cloud deployment in an existing cloud.",
321
- cls=AnyscaleCommand,
322
- example=command_examples.CLOUD_DEPLOYMENT_UPDATE_EXAMPLE,
323
- is_alpha=True,
324
- )
325
- @click.option(
326
- "--cloud",
327
- help="The name of the cloud that the cloud deployment belongs to.",
266
+ help="The name of the cloud to add the new resource to.",
328
267
  type=str,
329
268
  required=True,
330
269
  )
331
270
  @click.option(
332
271
  "--file",
333
272
  "-f",
334
- help="Path to a YAML file defining the cloud deployment. Schema: https://docs.anyscale.com/reference/cloud-api#clouddeployment.", # TODO(janet): check link
273
+ help="Path to a YAML file defining the cloud resource. Schema: https://docs.anyscale.com/reference/cloud/#cloudresource.",
335
274
  required=True,
336
275
  )
337
276
  @click.option(
338
277
  "--skip-verification",
339
278
  is_flag=True,
340
279
  default=False,
341
- help="Skip cloud deployment verification.",
280
+ help="Skip cloud resource verification.",
342
281
  )
343
282
  @click.option(
344
283
  "--yes", "-y", is_flag=True, default=False, help="Skip asking for confirmation."
345
284
  )
346
- def cloud_deployment_update(
347
- cloud: str, file: str, skip_verification: bool, yes: bool
285
+ def cloud_resource_create(
286
+ cloud: str, file: str, skip_verification: bool, yes: bool,
348
287
  ) -> None:
349
288
  try:
350
- CloudController().update_cloud_deployment(cloud, file, skip_verification, yes)
289
+ CloudController().create_cloud_resource(cloud, file, skip_verification, yes)
351
290
  except click.ClickException as e:
352
291
  print(e)
353
292
 
354
293
 
355
- @cloud_deployment_group.command(
294
+ @cloud_resource_group.command(
356
295
  name="delete",
357
- help="Remove a cloud deployment from an existing cloud.",
296
+ help="Remove a cloud resource from an existing cloud.",
358
297
  cls=AnyscaleCommand,
359
- example=command_examples.CLOUD_DEPLOYMENT_DELETE_EXAMPLE,
298
+ example=command_examples.CLOUD_RESOURCE_DELETE_EXAMPLE,
360
299
  is_alpha=True,
361
300
  )
362
301
  @click.option(
363
302
  "--cloud",
364
- help="The name of the cloud to remove the deployment from.",
303
+ help="The name of the cloud to remove the resource from.",
365
304
  type=str,
366
305
  required=True,
367
306
  )
368
307
  @click.option(
369
- "--deployment",
370
- help="The name of the deployment to remove.",
308
+ "--resource",
309
+ help="The name of the cloud resource to remove.",
371
310
  type=str,
372
311
  required=True,
373
312
  )
374
313
  @click.option(
375
314
  "--yes", "-y", is_flag=True, default=False, help="Skip asking for confirmation."
376
315
  )
377
- def cloud_deployment_delete(cloud: str, deployment: str, yes: bool,) -> None:
316
+ def cloud_resource_delete(cloud: str, resource: str, yes: bool,) -> None:
378
317
  try:
379
- CloudController().remove_cloud_deployment(cloud, deployment, yes)
318
+ CloudController().remove_cloud_resource(cloud, resource, yes)
380
319
  except click.ClickException as e:
381
320
  print(e)
382
321
 
383
322
 
384
323
  @cloud_cli.command(
385
- name="update",
386
- help=(
387
- "Update a managed cloud to the latest configuration. Only applicable for anyscale managed clouds."
388
- ),
324
+ name="update", help=("Update a cloud."),
389
325
  )
390
326
  @click.argument("cloud-name", required=False)
391
327
  @click.option(
@@ -422,6 +358,18 @@ def cloud_deployment_delete(cloud: str, deployment: str, yes: bool,) -> None:
422
358
  "are manually granted permissions to access the cloud. No existing cloud permissions are altered by specifying this flag."
423
359
  ),
424
360
  )
361
+ @click.option(
362
+ "--resources-file",
363
+ "-f",
364
+ help="EXPERIMENTAL: Path to a YAML file defining a list of cloud resources. Schema: https://docs.anyscale.com/reference/cloud/#cloudresource.",
365
+ required=False,
366
+ )
367
+ @click.option(
368
+ "--skip-verification",
369
+ is_flag=True,
370
+ default=False,
371
+ help="Skip cloud resource verification.",
372
+ )
425
373
  def cloud_update( # noqa: PLR0913
426
374
  cloud_name: Optional[str],
427
375
  name: Optional[str],
@@ -430,12 +378,23 @@ def cloud_update( # noqa: PLR0913
430
378
  enable_head_node_fault_tolerance: bool,
431
379
  yes: bool,
432
380
  enable_auto_add_user: Optional[bool],
381
+ resources_file: Optional[str],
382
+ skip_verification: bool,
433
383
  ) -> None:
434
384
  if cloud_name and name and cloud_name != name:
435
385
  raise click.ClickException(
436
386
  "The positional argument CLOUD_NAME and the keyword argument --name "
437
387
  "were both provided. Please only provide one of these two arguments."
438
388
  )
389
+ if resources_file:
390
+ CloudController().update_cloud_resources(
391
+ cloud_name=cloud_name or name,
392
+ cloud_id=cloud_id,
393
+ resources_file=resources_file,
394
+ skip_verification=skip_verification,
395
+ yes=yes,
396
+ )
397
+ return
439
398
  if enable_head_node_fault_tolerance and (enable_auto_add_user is not None):
440
399
  raise click.ClickException(
441
400
  "Please only specify either --enable-head-node-fault-tolerance or "
@@ -740,7 +699,7 @@ def cloud_config_update(
740
699
  )
741
700
  @click.option(
742
701
  "--cloud-storage-bucket-name",
743
- help="A fully qualified storage bucket name for cloud storage, e.g. s3://bucket-name, gs://bucket-name, or azure://bucket-name.",
702
+ help="A fully qualified storage bucket name for cloud storage, e.g. s3://bucket-name, gs://bucket-name, or abfss://bucket-name@account.dfs.core.windows.net.",
744
703
  required=False,
745
704
  type=str,
746
705
  )
@@ -769,6 +728,18 @@ def cloud_config_update(
769
728
  required=False,
770
729
  type=str,
771
730
  )
731
+ @click.option(
732
+ "--persistent-volume-claim",
733
+ help="For Kubernetes deployments only, the name of the persistent volume claim used to mount shared storage into pods. Mutually exclusive with NFS configurations.",
734
+ required=False,
735
+ type=str,
736
+ )
737
+ @click.option(
738
+ "--csi-ephemeral-volume-driver",
739
+ help="For Kubernetes deployments only, the CSI ephemeral volume driver used to mount shared storage into pods. Mutually exclusive with NFS configurations.",
740
+ required=False,
741
+ type=str,
742
+ )
772
743
  @click.option(
773
744
  "--memorystore-instance-name",
774
745
  help="Memorystore instance name for GCP clouds",
@@ -854,6 +825,8 @@ def register_cloud( # noqa: PLR0913, PLR0912, C901
854
825
  cloud_storage_bucket_region: Optional[str],
855
826
  nfs_mount_target: List[str],
856
827
  nfs_mount_path: str,
828
+ persistent_volume_claim: Optional[str],
829
+ csi_ephemeral_volume_driver: Optional[str],
857
830
  memorystore_instance_name: str,
858
831
  host_project_id: Optional[str],
859
832
  kubernetes_zones: Optional[str],
@@ -865,6 +838,30 @@ def register_cloud( # noqa: PLR0913, PLR0912, C901
865
838
  enable_auto_add_user: bool,
866
839
  ) -> None:
867
840
  missing_args: List[str] = []
841
+
842
+ # Validate K8S-only storage flags
843
+ if (
844
+ persistent_volume_claim or csi_ephemeral_volume_driver
845
+ ) and compute_stack != ComputeStack.K8S:
846
+ raise click.ClickException(
847
+ "--persistent-volume-claim and --csi-ephemeral-volume-driver are only supported with --compute-stack=k8s"
848
+ )
849
+
850
+ # Validate mutual exclusivity of storage configurations
851
+ storage_configs = []
852
+ if nfs_mount_target or nfs_mount_path:
853
+ storage_configs.append("NFS")
854
+ if persistent_volume_claim:
855
+ storage_configs.append("persistent volume claim")
856
+ if csi_ephemeral_volume_driver:
857
+ storage_configs.append("CSI ephemeral volume driver")
858
+
859
+ if len(storage_configs) > 1:
860
+ raise click.ClickException(
861
+ f"Storage configurations are mutually exclusive. Found: {', '.join(storage_configs)}. "
862
+ "Please specify only one of: --nfs-mount-target/--nfs-mount-path, --persistent-volume-claim, or --csi-ephemeral-volume-driver"
863
+ )
864
+
868
865
  if provider == "aws":
869
866
  if s3_bucket_id and not cloud_storage_bucket_name:
870
867
  cloud_storage_bucket_name = s3_bucket_id
@@ -927,6 +924,8 @@ def register_cloud( # noqa: PLR0913, PLR0912, C901
927
924
  skip_verifications=skip_verifications,
928
925
  auto_add_user=enable_auto_add_user,
929
926
  external_id=external_id,
927
+ persistent_volume_claim=persistent_volume_claim,
928
+ csi_ephemeral_volume_driver=csi_ephemeral_volume_driver,
930
929
  )
931
930
  elif provider == "gcp":
932
931
  if filestore_instance_id and not file_storage_id:
@@ -1039,6 +1038,8 @@ def register_cloud( # noqa: PLR0913, PLR0912, C901
1039
1038
  yes=yes,
1040
1039
  skip_verifications=skip_verifications,
1041
1040
  auto_add_user=enable_auto_add_user,
1041
+ persistent_volume_claim=persistent_volume_claim,
1042
+ csi_ephemeral_volume_driver=csi_ephemeral_volume_driver,
1042
1043
  )
1043
1044
  elif provider in ("azure", "generic"):
1044
1045
  # For the 'generic' provider type, for the time being, most fields are optional; only 'name', 'provider', and 'compute-stack' are required.
@@ -1060,6 +1061,8 @@ def register_cloud( # noqa: PLR0913, PLR0912, C901
1060
1061
  cloud_storage_bucket_region=cloud_storage_bucket_region,
1061
1062
  nfs_mount_targets=list(nfs_mount_target) if nfs_mount_target else [],
1062
1063
  nfs_mount_path=nfs_mount_path,
1064
+ persistent_volume_claim=persistent_volume_claim,
1065
+ csi_ephemeral_volume_driver=csi_ephemeral_volume_driver,
1063
1066
  kubernetes_zones=kubernetes_zones.split(",") if kubernetes_zones else [],
1064
1067
  anyscale_operator_iam_identity=anyscale_operator_iam_identity,
1065
1068
  )
@@ -1334,14 +1337,16 @@ def get_cloud(
1334
1337
  log.error("Cloud not found.")
1335
1338
  return
1336
1339
 
1337
- # Include all cloud deployments for the cloud.
1338
- cloud_deployments = CloudController().get_cloud_deployments(cloud_id=cloud.id)
1340
+ # Include all cloud resources for the cloud.
1341
+ cloud_resources = CloudController().get_formatted_cloud_resources(
1342
+ cloud_id=cloud.id
1343
+ )
1339
1344
  result = {
1340
1345
  "name": cloud.name,
1341
1346
  "id": cloud.id,
1342
1347
  "created_at": cloud.created_at,
1343
1348
  "is_default": cloud.is_default,
1344
- "deployments": cloud_deployments.get("deployments", []),
1349
+ "resources": cloud_resources,
1345
1350
  }
1346
1351
 
1347
1352
  if output:
@@ -498,6 +498,7 @@ $ anyscale organization-invitation delete --email test@anyscale.com
498
498
  (anyscale +0.6s) Organization invitation for test@anyscale.com deleted.
499
499
  """
500
500
 
501
+
501
502
  PROJECT_ADD_COLLABORATORS_EXAMPLE = """\
502
503
  $ anyscale project add-collaborators --cloud cloud_name --project project_name --users-file collaborators.yaml
503
504
  (anyscale +1.3s) Successfully added 3 collaborators to project project_name.
@@ -511,6 +512,32 @@ collaborators:
511
512
  permission_level: "owner"
512
513
  """
513
514
 
515
+
516
+ PROJECT_GET_EXAMPLE = """\
517
+ $ anyscale project get --id my-project-id
518
+ """
519
+
520
+
521
+ PROJECT_LIST_EXAMPLE = """\
522
+ $ anyscale project list --include-defaults --non-interactive --max-items 2
523
+ """
524
+
525
+
526
+ PROJECT_CREATE_EXAMPLE = """\
527
+ $ anyscale project create --name "my-project" --cloud "my-cloud-id"
528
+ """
529
+
530
+
531
+ PROJECT_DELETE_EXAMPLE = """\
532
+ $ anyscale project delete --id project-id
533
+ """
534
+
535
+
536
+ PROJECT_GET_DEFAULT_EXAMPLE = """\
537
+ $ anyscale project get-default --cloud my-cloud-id --json
538
+ """
539
+
540
+
514
541
  CLOUD_ADD_COLLABORATORS_EXAMPLE = """\
515
542
  $ anyscale cloud add-collaborators --cloud cloud_name --users-file collaborators.yaml
516
543
  (anyscale +1.3s) Successfully added 2 collaborators to cloud cloud_name.
@@ -522,34 +549,13 @@ collaborators:
522
549
  permission_level: "readonly"
523
550
  """
524
551
 
525
- CLOUD_DEPLOYMENT_CREATE_EXAMPLE = """\
526
- $ anyscale cloud deployment create --cloud my-cloud --file new-cloud-deployment.yaml
527
- Successfully created cloud deployment my-new-deployment in cloud my-cloud.
528
552
 
529
- $ cat new-cloud-deployment.yaml
530
- name: my-new-deployment
531
- provider: AWS
532
- compute_stack: VM
533
- region: us-west-2
534
- networking_mode: PUBLIC
535
- object_storage:
536
- bucket_name: s3://my-bucket
537
- file_storage:
538
- file_storage_id: fs-123
539
- aws_config:
540
- vpc_id: vpc-123
541
- subnet_ids:
542
- - subnet-123
543
- security_group_ids:
544
- - sg-123
545
- anyscale_iam_role_id: arn:aws:iam::123456789012:role/anyscale-role-123
546
- cluster_iam_role_id: arn:aws:iam::123456789012:role/cluster-role-123
547
- memorydb_cluster_name: my-memorydb-cluster
548
- """
553
+ CLOUD_RESOURCE_CREATE_EXAMPLE = """\
554
+ $ anyscale cloud resource create --cloud my-cloud --file new-cloud-resource.yaml
555
+ Successfully created cloud resource my-new-resource in cloud my-cloud.
549
556
 
550
- CLOUD_DEPLOYMENT_GET_EXAMPLE = """\
551
- $ anyscale cloud deployment get --cloud my-cloud --deployment my-deployment
552
- name: my-deployment
557
+ $ cat new-cloud-resource.yaml
558
+ name: my-new-resource
553
559
  provider: AWS
554
560
  compute_stack: VM
555
561
  region: us-west-2
@@ -569,29 +575,11 @@ aws_config:
569
575
  memorydb_cluster_name: my-memorydb-cluster
570
576
  """
571
577
 
572
-
573
- CLOUD_DEPLOYMENT_UPDATE_EXAMPLE = """\
574
- $ anyscale cloud deployment update --cloud my-cloud --file updated-cloud-deployment.yaml
575
- Output
576
- (anyscale +3.7s) Detected the following changes:
577
- --- +++ @@ -15,9 +15,9 @@ file_storage_id: fs-123
578
- -name: my-cloud-deployment
579
- +name: my-updated-cloud-deployment
580
- networking_mode: PUBLIC
581
- object_storage:
582
- - bucket_name: s3://my-bucket
583
- + bucket_name: s3://my-updated-bucket
584
- provider: AWS
585
- Would you like to proceed with updating this cloud deployment? [y/N]: y
586
- (anyscale +10.2s) Successfully updated cloud deployment my-updated-cloud-deployment in cloud my-cloud.
587
- """
588
-
589
-
590
- CLOUD_DEPLOYMENT_DELETE_EXAMPLE = """\
591
- $ anyscale cloud deployment delete --cloud my-cloud --deployment my-deployment
578
+ CLOUD_RESOURCE_DELETE_EXAMPLE = """\
579
+ $ anyscale cloud resource delete --cloud my-cloud --resource my-resource
592
580
  Output
593
- Please confirm that you would like to remove deployment my-deployment from cloud my-cloud. [y/N]: y
594
- (anyscale +3.5s) Successfully removed deployment my-deployment from cloud my-cloud!
581
+ Please confirm that you would like to remove resource my-resource from cloud my-cloud. [y/N]: y
582
+ (anyscale +3.5s) Successfully removed resource my-resource from cloud my-cloud!
595
583
  """
596
584
 
597
585
  CLOUD_GET_CLOUD_EXAMPLE = """\
@@ -601,7 +589,7 @@ name: my-cloud
601
589
  created_at: 2022-10-18 05:12:13.335803+00:00
602
590
  is_default: true
603
591
  deployments:
604
- - cloud_deployment_id: cldrsrc_123
592
+ - cloud_resource_id: cldrsrc_123
605
593
  name: vm-aws-us-west-2
606
594
  provider: AWS
607
595
  compute_stack: VM
@@ -1,14 +1,25 @@
1
1
  import click
2
2
 
3
+ from anyscale.commands.util import DeprecatedAnyscaleCommand
4
+
3
5
 
4
6
  @click.command(
5
7
  name="exec",
6
8
  hidden=True,
7
9
  help="[DEPRECATED] Execute shell commands in interactive cluster.",
8
10
  context_settings={"ignore_unknown_options": True, "allow_extra_args": True,},
11
+ cls=DeprecatedAnyscaleCommand,
12
+ removal_date="2025-10-01",
13
+ deprecation_message="`anyscale exec` has been deprecated and no longer works on Anyscale",
14
+ alternative="use `anyscale job submit` to run your script as a job in a cluster",
9
15
  )
10
16
  def anyscale_exec() -> None:
17
+ """Execute shell commands in interactive cluster.
18
+
19
+ DEPRECATED: This command will be removed on 2025-10-01.
20
+ Use 'anyscale job submit' to run your script as a job in a cluster.
21
+ """
11
22
  raise click.ClickException(
12
- "Warning: `anyscale exec` has been deprecated and no longer works on Anyscale V2. "
23
+ "`anyscale exec` has been deprecated and no longer works on Anyscale. "
13
24
  "Please use `anyscale job submit` to run your script as a job in a cluster."
14
25
  )