anyscale 0.26.42__py3-none-any.whl → 0.26.44__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.
- anyscale/_private/anyscale_client/common.py +1 -1
- anyscale/_private/docgen/__main__.py +2 -0
- anyscale/_private/docgen/models.md +2 -2
- anyscale/_private/workload/workload_sdk.py +6 -0
- anyscale/client/README.md +7 -0
- anyscale/client/openapi_client/__init__.py +6 -0
- anyscale/client/openapi_client/api/default_api.py +132 -0
- anyscale/client/openapi_client/models/__init__.py +6 -0
- anyscale/client/openapi_client/models/baseimagesenum.py +68 -1
- anyscale/client/openapi_client/models/describe_machine_pool_machines_filters.py +150 -0
- anyscale/client/openapi_client/models/describe_machine_pool_machines_request.py +31 -3
- anyscale/client/openapi_client/models/describe_machine_pool_requests_request.py +31 -3
- anyscale/client/openapi_client/models/describe_machine_pool_workloads_filters.py +150 -0
- anyscale/client/openapi_client/models/describe_machine_pool_workloads_request.py +151 -0
- anyscale/client/openapi_client/models/file_storage.py +33 -5
- anyscale/client/openapi_client/models/supportedbaseimagesenum.py +68 -1
- anyscale/client/openapi_client/models/workload_machine_info.py +210 -0
- anyscale/client/openapi_client/models/workload_state_info.py +295 -0
- anyscale/client/openapi_client/models/workloadstateinfo_list_response.py +147 -0
- anyscale/commands/cloud_commands.py +1 -0
- anyscale/commands/compute_config_commands.py +10 -3
- anyscale/compute_config/__init__.py +16 -0
- anyscale/compute_config/_private/compute_config_sdk.py +176 -61
- anyscale/compute_config/commands.py +66 -1
- anyscale/compute_config/models.py +160 -3
- anyscale/conf.py +1 -1
- anyscale/controllers/cloud_controller.py +149 -9
- anyscale/job/_private/job_sdk.py +22 -0
- anyscale/sdk/anyscale_client/models/baseimagesenum.py +68 -1
- anyscale/sdk/anyscale_client/models/supportedbaseimagesenum.py +68 -1
- anyscale/shared_anyscale_utils/latest_ray_version.py +1 -1
- anyscale/version.py +1 -1
- {anyscale-0.26.42.dist-info → anyscale-0.26.44.dist-info}/METADATA +16 -16
- {anyscale-0.26.42.dist-info → anyscale-0.26.44.dist-info}/RECORD +39 -33
- {anyscale-0.26.42.dist-info → anyscale-0.26.44.dist-info}/LICENSE +0 -0
- {anyscale-0.26.42.dist-info → anyscale-0.26.44.dist-info}/NOTICE +0 -0
- {anyscale-0.26.42.dist-info → anyscale-0.26.44.dist-info}/WHEEL +0 -0
- {anyscale-0.26.42.dist-info → anyscale-0.26.44.dist-info}/entry_points.txt +0 -0
- {anyscale-0.26.42.dist-info → anyscale-0.26.44.dist-info}/top_level.txt +0 -0
|
@@ -269,14 +269,16 @@ class CloudController(BaseController):
|
|
|
269
269
|
"ParameterKey": "MemoryDBRedisPort",
|
|
270
270
|
"ParameterValue": MEMORYDB_REDIS_PORT,
|
|
271
271
|
},
|
|
272
|
-
{
|
|
273
|
-
"ParameterKey": "EnableEFS",
|
|
274
|
-
"ParameterValue": "true"
|
|
275
|
-
if shared_storage == SharedStorageType.NFS
|
|
276
|
-
else "false",
|
|
277
|
-
},
|
|
278
272
|
]
|
|
279
273
|
if not is_anyscale_hosted:
|
|
274
|
+
parameters.append(
|
|
275
|
+
{
|
|
276
|
+
"ParameterKey": "EnableEFS",
|
|
277
|
+
"ParameterValue": "true"
|
|
278
|
+
if shared_storage == SharedStorageType.NFS
|
|
279
|
+
else "false",
|
|
280
|
+
}
|
|
281
|
+
)
|
|
280
282
|
parameters.append(
|
|
281
283
|
{
|
|
282
284
|
"ParameterKey": "AnyscaleCrossAccountIAMRoleName",
|
|
@@ -2220,6 +2222,7 @@ class CloudController(BaseController):
|
|
|
2220
2222
|
nfs_mount_targets: Optional[List[str]] = None,
|
|
2221
2223
|
nfs_mount_path: Optional[str] = None,
|
|
2222
2224
|
kubernetes_zones: Optional[List[str]] = None,
|
|
2225
|
+
anyscale_operator_iam_identity: Optional[str] = None,
|
|
2223
2226
|
) -> None:
|
|
2224
2227
|
cloud_provider = (
|
|
2225
2228
|
CloudProviders.AZURE if provider == "azure" else CloudProviders.GENERIC
|
|
@@ -2313,8 +2316,28 @@ class CloudController(BaseController):
|
|
|
2313
2316
|
|
|
2314
2317
|
# TODO (shomilj): Fetch & optionally run the Helm installation here.
|
|
2315
2318
|
cloud_resource_id = cloud_resource.result.cloud_resource.id
|
|
2319
|
+
# For Azure and generic providers, add CLI token to helm command
|
|
2320
|
+
if provider in ["azure", "generic"]:
|
|
2321
|
+
helm_command = self._generate_helm_upgrade_command(
|
|
2322
|
+
provider=provider,
|
|
2323
|
+
cloud_deployment_id=cloud_resource_id,
|
|
2324
|
+
region=region if provider != "generic" else None,
|
|
2325
|
+
kubernetes_zones=kubernetes_zones,
|
|
2326
|
+
operator_iam_identity=anyscale_operator_iam_identity
|
|
2327
|
+
if provider == "azure"
|
|
2328
|
+
else None,
|
|
2329
|
+
anyscale_cli_token=None, # TODO: use $ANYSCALE_CLI_TOKEN placeholder
|
|
2330
|
+
)
|
|
2331
|
+
else:
|
|
2332
|
+
helm_command = self._generate_helm_upgrade_command(
|
|
2333
|
+
provider=provider,
|
|
2334
|
+
cloud_deployment_id=cloud_resource_id,
|
|
2335
|
+
region=region,
|
|
2336
|
+
kubernetes_zones=kubernetes_zones,
|
|
2337
|
+
)
|
|
2338
|
+
|
|
2316
2339
|
self.log.info(
|
|
2317
|
-
f"Cloud registration complete!
|
|
2340
|
+
f"Cloud registration complete! To install the Anyscale operator, run:\n\n{helm_command}"
|
|
2318
2341
|
)
|
|
2319
2342
|
|
|
2320
2343
|
def register_aws_cloud( # noqa: PLR0913, PLR0912, C901
|
|
@@ -2580,8 +2603,14 @@ class CloudController(BaseController):
|
|
|
2580
2603
|
self.wait_for_cloud_to_be_active(cloud_id, CloudProviders.AWS)
|
|
2581
2604
|
if compute_stack == ComputeStack.K8S:
|
|
2582
2605
|
cloud_resource_id = cloud_resource.result.cloud_resource.id
|
|
2606
|
+
helm_command = self._generate_helm_upgrade_command(
|
|
2607
|
+
provider="aws",
|
|
2608
|
+
cloud_deployment_id=cloud_resource_id,
|
|
2609
|
+
region=region,
|
|
2610
|
+
kubernetes_zones=kubernetes_zones,
|
|
2611
|
+
)
|
|
2583
2612
|
self.log.info(
|
|
2584
|
-
f"
|
|
2613
|
+
f"Cloud registration complete! To install the Anyscale operator, run:\n\n{helm_command}"
|
|
2585
2614
|
)
|
|
2586
2615
|
self.cloud_event_producer.produce(
|
|
2587
2616
|
CloudAnalyticsEventName.INFRA_SETUP_COMPLETE, succeeded=True
|
|
@@ -2966,8 +2995,20 @@ class CloudController(BaseController):
|
|
|
2966
2995
|
self.wait_for_cloud_to_be_active(cloud_id, CloudProviders.GCP)
|
|
2967
2996
|
if compute_stack == ComputeStack.K8S:
|
|
2968
2997
|
cloud_resource_id = cloud_resource.result.cloud_resource.id
|
|
2998
|
+
helm_command = self._generate_helm_upgrade_command(
|
|
2999
|
+
provider="gcp",
|
|
3000
|
+
cloud_deployment_id=cloud_resource_id,
|
|
3001
|
+
region=region,
|
|
3002
|
+
kubernetes_zones=kubernetes_zones,
|
|
3003
|
+
operator_iam_identity=anyscale_service_account_email,
|
|
3004
|
+
)
|
|
3005
|
+
gcloud_command = self._generate_gcp_workload_identity_command(
|
|
3006
|
+
anyscale_service_account_email=anyscale_service_account_email,
|
|
3007
|
+
project_id=project_id,
|
|
3008
|
+
namespace="<namespace>",
|
|
3009
|
+
)
|
|
2969
3010
|
self.log.info(
|
|
2970
|
-
f"
|
|
3011
|
+
f"Cloud registration complete! To install the Anyscale operator, run:\n\n{helm_command}\n\nThen configure workload identity by running:\n\n{gcloud_command}"
|
|
2971
3012
|
)
|
|
2972
3013
|
self.cloud_event_producer.produce(
|
|
2973
3014
|
CloudAnalyticsEventName.INFRA_SETUP_COMPLETE, succeeded=True
|
|
@@ -3682,6 +3723,105 @@ class CloudController(BaseController):
|
|
|
3682
3723
|
)
|
|
3683
3724
|
return rollback_cmd
|
|
3684
3725
|
|
|
3726
|
+
def _generate_helm_upgrade_command(
|
|
3727
|
+
self,
|
|
3728
|
+
provider: str,
|
|
3729
|
+
cloud_deployment_id: str,
|
|
3730
|
+
region: Optional[str] = None,
|
|
3731
|
+
kubernetes_zones: Optional[List[str]] = None,
|
|
3732
|
+
operator_iam_identity: Optional[str] = None,
|
|
3733
|
+
anyscale_cli_token: Optional[str] = None,
|
|
3734
|
+
) -> str:
|
|
3735
|
+
"""
|
|
3736
|
+
Generate the helm upgrade command for installing the Anyscale operator.
|
|
3737
|
+
|
|
3738
|
+
Args:
|
|
3739
|
+
provider: Cloud provider ('aws', 'gcp', 'azure', 'generic')
|
|
3740
|
+
cloud_deployment_id: The cloud deployment ID from registration
|
|
3741
|
+
region: Cloud region (optional for generic provider)
|
|
3742
|
+
kubernetes_zones: Optional list of Kubernetes zones
|
|
3743
|
+
operator_iam_identity: IAM identity for the operator (GCP service account email, Azure client ID)
|
|
3744
|
+
anyscale_cli_token: CLI token (required for Azure and generic providers)
|
|
3745
|
+
|
|
3746
|
+
Returns:
|
|
3747
|
+
Formatted helm upgrade command string
|
|
3748
|
+
"""
|
|
3749
|
+
command_parts = [
|
|
3750
|
+
"helm upgrade <release-name> anyscale/anyscale-operator",
|
|
3751
|
+
f" --set-string cloudDeploymentId={cloud_deployment_id}",
|
|
3752
|
+
f" --set-string cloudProvider={provider}",
|
|
3753
|
+
]
|
|
3754
|
+
|
|
3755
|
+
# Add region for most providers (not for generic)
|
|
3756
|
+
if region and provider != "generic":
|
|
3757
|
+
command_parts.append(f" --set-string region={region}")
|
|
3758
|
+
|
|
3759
|
+
# Add provider-specific parameters
|
|
3760
|
+
if provider == "gcp" and operator_iam_identity:
|
|
3761
|
+
command_parts.append(
|
|
3762
|
+
f" --set-string operatorIamIdentity={operator_iam_identity}"
|
|
3763
|
+
)
|
|
3764
|
+
elif provider == "azure":
|
|
3765
|
+
if operator_iam_identity:
|
|
3766
|
+
command_parts.append(
|
|
3767
|
+
f" --set-string operatorIamIdentity={operator_iam_identity}"
|
|
3768
|
+
)
|
|
3769
|
+
if anyscale_cli_token:
|
|
3770
|
+
command_parts.append(
|
|
3771
|
+
f" --set-string anyscaleCliToken={anyscale_cli_token}"
|
|
3772
|
+
)
|
|
3773
|
+
else:
|
|
3774
|
+
command_parts.append(
|
|
3775
|
+
" --set-string anyscaleCliToken=$ANYSCALE_CLI_TOKEN"
|
|
3776
|
+
)
|
|
3777
|
+
elif provider == "generic":
|
|
3778
|
+
if anyscale_cli_token:
|
|
3779
|
+
command_parts.append(
|
|
3780
|
+
f" --set-string anyscaleCliToken={anyscale_cli_token}"
|
|
3781
|
+
)
|
|
3782
|
+
else:
|
|
3783
|
+
command_parts.append(
|
|
3784
|
+
" --set-string anyscaleCliToken=$ANYSCALE_CLI_TOKEN"
|
|
3785
|
+
)
|
|
3786
|
+
|
|
3787
|
+
# Add common parameters
|
|
3788
|
+
command_parts.extend(
|
|
3789
|
+
[
|
|
3790
|
+
" --set-string workloadServiceAccountName=anyscale-operator",
|
|
3791
|
+
" --namespace <namespace>",
|
|
3792
|
+
" --create-namespace",
|
|
3793
|
+
" -i",
|
|
3794
|
+
]
|
|
3795
|
+
)
|
|
3796
|
+
|
|
3797
|
+
# Add zones if provided (mainly for K8s deployments)
|
|
3798
|
+
if kubernetes_zones:
|
|
3799
|
+
zones_str = ",".join(kubernetes_zones)
|
|
3800
|
+
command_parts.append(f" --set-string zones={zones_str}")
|
|
3801
|
+
|
|
3802
|
+
return " \\\n".join(command_parts)
|
|
3803
|
+
|
|
3804
|
+
def _generate_gcp_workload_identity_command(
|
|
3805
|
+
self,
|
|
3806
|
+
anyscale_service_account_email: str,
|
|
3807
|
+
project_id: str,
|
|
3808
|
+
namespace: str = "<namespace>",
|
|
3809
|
+
) -> str:
|
|
3810
|
+
"""
|
|
3811
|
+
Generate the gcloud command for setting up workload identity for GCP.
|
|
3812
|
+
|
|
3813
|
+
Args:
|
|
3814
|
+
anyscale_service_account_email: The GCP service account email
|
|
3815
|
+
project_id: The GCP project ID
|
|
3816
|
+
namespace: The Kubernetes namespace (defaults to <namespace> placeholder)
|
|
3817
|
+
|
|
3818
|
+
Returns:
|
|
3819
|
+
Formatted gcloud iam service-accounts add-iam-policy-binding command
|
|
3820
|
+
"""
|
|
3821
|
+
return f"""gcloud iam service-accounts add-iam-policy-binding {anyscale_service_account_email} \\
|
|
3822
|
+
--role roles/iam.workloadIdentityUser \\
|
|
3823
|
+
--member "serviceAccount:{project_id}.svc.id.goog[{namespace}/anyscale-operator]" """
|
|
3824
|
+
|
|
3685
3825
|
def _edit_gcp_cloud( # noqa: PLR0912
|
|
3686
3826
|
self,
|
|
3687
3827
|
*,
|
anyscale/job/_private/job_sdk.py
CHANGED
|
@@ -87,6 +87,9 @@ class PrivateJobSDK(WorkloadSDK):
|
|
|
87
87
|
autopopulate_in_workspace=autopopulate_in_workspace,
|
|
88
88
|
additional_py_modules=config.py_modules,
|
|
89
89
|
py_executable_override=config.py_executable,
|
|
90
|
+
has_multiple_cloud_deployments=self._compute_config_has_multiple_cloud_deployments(
|
|
91
|
+
config.compute_config
|
|
92
|
+
),
|
|
90
93
|
)
|
|
91
94
|
[runtime_env] = self.override_and_load_requirements_files(
|
|
92
95
|
[runtime_env],
|
|
@@ -99,6 +102,25 @@ class PrivateJobSDK(WorkloadSDK):
|
|
|
99
102
|
|
|
100
103
|
return runtime_env or None
|
|
101
104
|
|
|
105
|
+
def _compute_config_has_multiple_cloud_deployments(
|
|
106
|
+
self, compute_config: Union[ComputeConfig, Dict, str, None]
|
|
107
|
+
) -> bool:
|
|
108
|
+
if not isinstance(compute_config, str):
|
|
109
|
+
# Multi-deployment compute configs are not supported in-line, only by name.
|
|
110
|
+
return False
|
|
111
|
+
|
|
112
|
+
compute_config_id = self._resolve_compute_config_id(
|
|
113
|
+
compute_config=compute_config
|
|
114
|
+
)
|
|
115
|
+
compute_template = self._client.get_compute_config(compute_config_id)
|
|
116
|
+
if compute_template is None or compute_template.config is None:
|
|
117
|
+
raise ValueError(f"The compute config '{compute_config}' does not exist.")
|
|
118
|
+
|
|
119
|
+
return (
|
|
120
|
+
compute_template.config.deployment_configs
|
|
121
|
+
and len(compute_template.config.deployment_configs) > 1
|
|
122
|
+
)
|
|
123
|
+
|
|
102
124
|
def get_default_name(self) -> str:
|
|
103
125
|
"""Get a default name for the job.
|
|
104
126
|
|