dstack 0.18.44__py3-none-any.whl → 0.19.0rc1__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.
- dstack/_internal/cli/commands/gateway.py +15 -3
- dstack/_internal/cli/commands/logs.py +0 -22
- dstack/_internal/cli/commands/stats.py +8 -17
- dstack/_internal/cli/main.py +1 -5
- dstack/_internal/cli/services/configurators/fleet.py +4 -39
- dstack/_internal/cli/services/configurators/run.py +22 -21
- dstack/_internal/cli/services/profile.py +34 -83
- dstack/_internal/cli/utils/gateway.py +1 -1
- dstack/_internal/core/backends/__init__.py +56 -39
- dstack/_internal/core/backends/aws/__init__.py +0 -25
- dstack/_internal/core/backends/aws/auth.py +1 -10
- dstack/_internal/core/backends/aws/backend.py +26 -0
- dstack/_internal/core/backends/aws/compute.py +20 -45
- dstack/_internal/{server/services/backends/configurators/aws.py → core/backends/aws/configurator.py} +46 -85
- dstack/_internal/core/backends/aws/models.py +135 -0
- dstack/_internal/core/backends/aws/resources.py +1 -1
- dstack/_internal/core/backends/azure/__init__.py +0 -20
- dstack/_internal/core/backends/azure/auth.py +2 -11
- dstack/_internal/core/backends/azure/backend.py +21 -0
- dstack/_internal/core/backends/azure/compute.py +13 -27
- dstack/_internal/{server/services/backends/configurators/azure.py → core/backends/azure/configurator.py} +141 -210
- dstack/_internal/core/backends/azure/models.py +89 -0
- dstack/_internal/core/backends/base/__init__.py +0 -12
- dstack/_internal/core/backends/base/backend.py +18 -0
- dstack/_internal/core/backends/base/compute.py +153 -33
- dstack/_internal/core/backends/base/configurator.py +105 -0
- dstack/_internal/core/backends/base/models.py +14 -0
- dstack/_internal/core/backends/configurators.py +138 -0
- dstack/_internal/core/backends/cudo/__init__.py +0 -15
- dstack/_internal/core/backends/cudo/backend.py +16 -0
- dstack/_internal/core/backends/cudo/compute.py +8 -26
- dstack/_internal/core/backends/cudo/configurator.py +72 -0
- dstack/_internal/core/backends/cudo/models.py +37 -0
- dstack/_internal/core/backends/datacrunch/__init__.py +0 -15
- dstack/_internal/core/backends/datacrunch/backend.py +16 -0
- dstack/_internal/core/backends/datacrunch/compute.py +8 -25
- dstack/_internal/core/backends/datacrunch/configurator.py +66 -0
- dstack/_internal/core/backends/datacrunch/models.py +38 -0
- dstack/_internal/core/{models/backends/dstack.py → backends/dstack/models.py} +7 -7
- dstack/_internal/core/backends/gcp/__init__.py +0 -16
- dstack/_internal/core/backends/gcp/auth.py +2 -11
- dstack/_internal/core/backends/gcp/backend.py +17 -0
- dstack/_internal/core/backends/gcp/compute.py +13 -43
- dstack/_internal/{server/services/backends/configurators/gcp.py → core/backends/gcp/configurator.py} +46 -103
- dstack/_internal/core/backends/gcp/models.py +125 -0
- dstack/_internal/core/backends/kubernetes/__init__.py +0 -15
- dstack/_internal/core/backends/kubernetes/backend.py +16 -0
- dstack/_internal/core/backends/kubernetes/compute.py +16 -5
- dstack/_internal/core/backends/kubernetes/configurator.py +55 -0
- dstack/_internal/core/backends/kubernetes/models.py +72 -0
- dstack/_internal/core/backends/lambdalabs/__init__.py +0 -16
- dstack/_internal/core/backends/lambdalabs/backend.py +17 -0
- dstack/_internal/core/backends/lambdalabs/compute.py +7 -28
- dstack/_internal/core/backends/lambdalabs/configurator.py +82 -0
- dstack/_internal/core/backends/lambdalabs/models.py +37 -0
- dstack/_internal/core/backends/local/__init__.py +0 -13
- dstack/_internal/core/backends/local/backend.py +14 -0
- dstack/_internal/core/backends/local/compute.py +16 -2
- dstack/_internal/core/backends/models.py +128 -0
- dstack/_internal/core/backends/oci/__init__.py +0 -15
- dstack/_internal/core/backends/oci/auth.py +1 -5
- dstack/_internal/core/backends/oci/backend.py +16 -0
- dstack/_internal/core/backends/oci/compute.py +9 -23
- dstack/_internal/{server/services/backends/configurators/oci.py → core/backends/oci/configurator.py} +40 -85
- dstack/_internal/core/{models/backends/oci.py → backends/oci/models.py} +24 -25
- dstack/_internal/core/backends/oci/region.py +1 -1
- dstack/_internal/core/backends/runpod/__init__.py +0 -15
- dstack/_internal/core/backends/runpod/backend.py +16 -0
- dstack/_internal/core/backends/runpod/compute.py +7 -3
- dstack/_internal/core/backends/runpod/configurator.py +59 -0
- dstack/_internal/core/backends/runpod/models.py +54 -0
- dstack/_internal/core/backends/template/__init__.py +0 -0
- dstack/_internal/core/backends/tensordock/__init__.py +0 -15
- dstack/_internal/core/backends/tensordock/backend.py +16 -0
- dstack/_internal/core/backends/tensordock/compute.py +8 -27
- dstack/_internal/core/backends/tensordock/configurator.py +68 -0
- dstack/_internal/core/backends/tensordock/models.py +38 -0
- dstack/_internal/core/backends/vastai/__init__.py +0 -15
- dstack/_internal/core/backends/vastai/backend.py +16 -0
- dstack/_internal/core/backends/vastai/compute.py +2 -2
- dstack/_internal/core/backends/vastai/configurator.py +66 -0
- dstack/_internal/core/backends/vastai/models.py +37 -0
- dstack/_internal/core/backends/vultr/__init__.py +0 -15
- dstack/_internal/core/backends/vultr/backend.py +16 -0
- dstack/_internal/core/backends/vultr/compute.py +10 -24
- dstack/_internal/core/backends/vultr/configurator.py +64 -0
- dstack/_internal/core/backends/vultr/models.py +34 -0
- dstack/_internal/core/models/backends/__init__.py +0 -184
- dstack/_internal/core/models/backends/base.py +0 -19
- dstack/_internal/core/models/configurations.py +20 -15
- dstack/_internal/core/models/envs.py +4 -3
- dstack/_internal/core/models/fleets.py +17 -22
- dstack/_internal/core/models/gateways.py +3 -3
- dstack/_internal/core/models/instances.py +24 -0
- dstack/_internal/core/models/profiles.py +41 -46
- dstack/_internal/core/models/projects.py +1 -1
- dstack/_internal/core/models/repos/base.py +0 -5
- dstack/_internal/core/models/repos/local.py +3 -3
- dstack/_internal/core/models/repos/remote.py +26 -12
- dstack/_internal/core/models/repos/virtual.py +1 -1
- dstack/_internal/core/models/resources.py +45 -76
- dstack/_internal/core/models/runs.py +17 -19
- dstack/_internal/core/models/volumes.py +1 -3
- dstack/_internal/core/services/profiles.py +7 -16
- dstack/_internal/core/services/repos.py +0 -4
- dstack/_internal/server/app.py +0 -3
- dstack/_internal/server/background/tasks/process_gateways.py +4 -8
- dstack/_internal/server/background/tasks/process_instances.py +14 -9
- dstack/_internal/server/background/tasks/process_metrics.py +1 -1
- dstack/_internal/server/background/tasks/process_placement_groups.py +4 -1
- dstack/_internal/server/background/tasks/process_prometheus_metrics.py +1 -1
- dstack/_internal/server/background/tasks/process_running_jobs.py +14 -5
- dstack/_internal/server/background/tasks/process_submitted_jobs.py +16 -37
- dstack/_internal/server/background/tasks/process_volumes.py +5 -2
- dstack/_internal/server/migrations/versions/7bc2586e8b9e_make_instancemodel_pool_id_optional.py +36 -0
- dstack/_internal/server/migrations/versions/bc8ca4a505c6_store_backendtype_as_string.py +171 -0
- dstack/_internal/server/models.py +48 -9
- dstack/_internal/server/routers/backends.py +14 -23
- dstack/_internal/server/routers/instances.py +3 -4
- dstack/_internal/server/routers/metrics.py +10 -8
- dstack/_internal/server/routers/prometheus.py +1 -1
- dstack/_internal/server/routers/repos.py +1 -2
- dstack/_internal/server/routers/runs.py +13 -59
- dstack/_internal/server/schemas/gateways.py +14 -23
- dstack/_internal/server/schemas/projects.py +7 -2
- dstack/_internal/server/schemas/repos.py +2 -38
- dstack/_internal/server/schemas/runner.py +1 -0
- dstack/_internal/server/schemas/runs.py +1 -24
- dstack/_internal/server/services/backends/__init__.py +85 -158
- dstack/_internal/server/services/config.py +52 -576
- dstack/_internal/server/services/fleets.py +8 -103
- dstack/_internal/server/services/gateways/__init__.py +12 -4
- dstack/_internal/server/services/{pools.py → instances.py} +22 -329
- dstack/_internal/server/services/jobs/__init__.py +9 -6
- dstack/_internal/server/services/jobs/configurators/base.py +16 -0
- dstack/_internal/server/services/jobs/configurators/dev.py +9 -1
- dstack/_internal/server/services/jobs/configurators/extensions/cursor.py +42 -0
- dstack/_internal/server/services/metrics.py +39 -13
- dstack/_internal/server/services/offers.py +1 -1
- dstack/_internal/server/services/projects.py +23 -14
- dstack/_internal/server/services/prometheus.py +176 -18
- dstack/_internal/server/services/runs.py +24 -16
- dstack/_internal/server/services/volumes.py +8 -4
- dstack/_internal/server/statics/index.html +1 -1
- dstack/_internal/server/statics/{main-4eb116b97819badd1e2c.js → main-4fd5a4770eff59325ee3.js} +7 -7
- dstack/_internal/server/statics/{main-4eb116b97819badd1e2c.js.map → main-4fd5a4770eff59325ee3.js.map} +1 -1
- dstack/_internal/server/testing/common.py +58 -32
- dstack/_internal/utils/json_schema.py +6 -0
- dstack/_internal/utils/ssh.py +2 -1
- dstack/api/__init__.py +4 -0
- dstack/api/_public/__init__.py +16 -20
- dstack/api/_public/backends.py +1 -1
- dstack/api/_public/repos.py +36 -36
- dstack/api/_public/runs.py +167 -83
- dstack/api/server/__init__.py +11 -13
- dstack/api/server/_backends.py +12 -16
- dstack/api/server/_fleets.py +15 -57
- dstack/api/server/_gateways.py +3 -14
- dstack/api/server/_repos.py +1 -4
- dstack/api/server/_runs.py +21 -100
- dstack/api/server/_volumes.py +10 -5
- dstack/version.py +1 -1
- {dstack-0.18.44.dist-info → dstack-0.19.0rc1.dist-info}/METADATA +1 -1
- {dstack-0.18.44.dist-info → dstack-0.19.0rc1.dist-info}/RECORD +218 -204
- tests/_internal/cli/services/configurators/test_profile.py +6 -6
- tests/_internal/core/backends/aws/test_configurator.py +35 -0
- tests/_internal/core/backends/aws/test_resources.py +1 -1
- tests/_internal/core/backends/azure/test_configurator.py +61 -0
- tests/_internal/core/backends/cudo/__init__.py +0 -0
- tests/_internal/core/backends/cudo/test_configurator.py +37 -0
- tests/_internal/core/backends/datacrunch/__init__.py +0 -0
- tests/_internal/core/backends/datacrunch/test_configurator.py +17 -0
- tests/_internal/core/backends/gcp/test_configurator.py +42 -0
- tests/_internal/core/backends/kubernetes/test_configurator.py +43 -0
- tests/_internal/core/backends/lambdalabs/__init__.py +0 -0
- tests/_internal/core/backends/lambdalabs/test_configurator.py +38 -0
- tests/_internal/core/backends/oci/test_configurator.py +55 -0
- tests/_internal/core/backends/runpod/__init__.py +0 -0
- tests/_internal/core/backends/runpod/test_configurator.py +33 -0
- tests/_internal/core/backends/tensordock/__init__.py +0 -0
- tests/_internal/core/backends/tensordock/test_configurator.py +38 -0
- tests/_internal/core/backends/vastai/__init__.py +0 -0
- tests/_internal/core/backends/vastai/test_configurator.py +33 -0
- tests/_internal/core/backends/vultr/__init__.py +0 -0
- tests/_internal/core/backends/vultr/test_configurator.py +33 -0
- tests/_internal/server/background/tasks/test_process_gateways.py +4 -0
- tests/_internal/server/background/tasks/test_process_instances.py +49 -48
- tests/_internal/server/background/tasks/test_process_metrics.py +0 -3
- tests/_internal/server/background/tasks/test_process_placement_groups.py +2 -0
- tests/_internal/server/background/tasks/test_process_prometheus_metrics.py +0 -3
- tests/_internal/server/background/tasks/test_process_running_jobs.py +0 -21
- tests/_internal/server/background/tasks/test_process_runs.py +8 -22
- tests/_internal/server/background/tasks/test_process_submitted_jobs.py +3 -40
- tests/_internal/server/background/tasks/test_process_submitted_volumes.py +2 -0
- tests/_internal/server/background/tasks/test_process_terminating_jobs.py +10 -15
- tests/_internal/server/routers/test_backends.py +6 -764
- tests/_internal/server/routers/test_fleets.py +0 -26
- tests/_internal/server/routers/test_gateways.py +27 -3
- tests/_internal/server/routers/test_instances.py +0 -10
- tests/_internal/server/routers/test_metrics.py +27 -0
- tests/_internal/server/routers/test_projects.py +56 -0
- tests/_internal/server/routers/test_prometheus.py +116 -27
- tests/_internal/server/routers/test_repos.py +0 -15
- tests/_internal/server/routers/test_runs.py +4 -219
- tests/_internal/server/routers/test_volumes.py +2 -3
- tests/_internal/server/services/backends/__init__.py +0 -0
- tests/_internal/server/services/jobs/configurators/test_task.py +35 -0
- tests/_internal/server/services/test_config.py +7 -4
- tests/_internal/server/services/test_fleets.py +1 -4
- tests/_internal/server/services/{test_pools.py → test_instances.py} +11 -49
- tests/_internal/server/services/test_metrics.py +9 -5
- tests/_internal/server/services/test_repos.py +1 -14
- tests/_internal/server/services/test_runs.py +0 -4
- dstack/_internal/cli/commands/pool.py +0 -581
- dstack/_internal/cli/commands/run.py +0 -75
- dstack/_internal/core/backends/aws/config.py +0 -18
- dstack/_internal/core/backends/azure/config.py +0 -12
- dstack/_internal/core/backends/base/config.py +0 -5
- dstack/_internal/core/backends/cudo/config.py +0 -9
- dstack/_internal/core/backends/datacrunch/config.py +0 -9
- dstack/_internal/core/backends/gcp/config.py +0 -22
- dstack/_internal/core/backends/kubernetes/config.py +0 -6
- dstack/_internal/core/backends/lambdalabs/config.py +0 -9
- dstack/_internal/core/backends/nebius/__init__.py +0 -15
- dstack/_internal/core/backends/nebius/api_client.py +0 -319
- dstack/_internal/core/backends/nebius/compute.py +0 -220
- dstack/_internal/core/backends/nebius/config.py +0 -6
- dstack/_internal/core/backends/nebius/types.py +0 -37
- dstack/_internal/core/backends/oci/config.py +0 -6
- dstack/_internal/core/backends/runpod/config.py +0 -17
- dstack/_internal/core/backends/tensordock/config.py +0 -9
- dstack/_internal/core/backends/vastai/config.py +0 -6
- dstack/_internal/core/backends/vultr/config.py +0 -9
- dstack/_internal/core/models/backends/aws.py +0 -86
- dstack/_internal/core/models/backends/azure.py +0 -68
- dstack/_internal/core/models/backends/cudo.py +0 -43
- dstack/_internal/core/models/backends/datacrunch.py +0 -44
- dstack/_internal/core/models/backends/gcp.py +0 -67
- dstack/_internal/core/models/backends/kubernetes.py +0 -40
- dstack/_internal/core/models/backends/lambdalabs.py +0 -43
- dstack/_internal/core/models/backends/nebius.py +0 -54
- dstack/_internal/core/models/backends/runpod.py +0 -42
- dstack/_internal/core/models/backends/tensordock.py +0 -44
- dstack/_internal/core/models/backends/vastai.py +0 -43
- dstack/_internal/core/models/backends/vultr.py +0 -40
- dstack/_internal/core/models/pools.py +0 -43
- dstack/_internal/server/routers/pools.py +0 -142
- dstack/_internal/server/schemas/pools.py +0 -38
- dstack/_internal/server/services/backends/configurators/base.py +0 -72
- dstack/_internal/server/services/backends/configurators/cudo.py +0 -87
- dstack/_internal/server/services/backends/configurators/datacrunch.py +0 -79
- dstack/_internal/server/services/backends/configurators/kubernetes.py +0 -63
- dstack/_internal/server/services/backends/configurators/lambdalabs.py +0 -98
- dstack/_internal/server/services/backends/configurators/nebius.py +0 -85
- dstack/_internal/server/services/backends/configurators/runpod.py +0 -67
- dstack/_internal/server/services/backends/configurators/tensordock.py +0 -82
- dstack/_internal/server/services/backends/configurators/vastai.py +0 -80
- dstack/_internal/server/services/backends/configurators/vultr.py +0 -80
- dstack/api/_public/pools.py +0 -41
- dstack/api/_public/resources.py +0 -105
- dstack/api/server/_pools.py +0 -63
- tests/_internal/server/routers/test_pools.py +0 -612
- /dstack/_internal/{server/services/backends/configurators → core/backends/dstack}/__init__.py +0 -0
- {dstack-0.18.44.dist-info → dstack-0.19.0rc1.dist-info}/LICENSE.md +0 -0
- {dstack-0.18.44.dist-info → dstack-0.19.0rc1.dist-info}/WHEEL +0 -0
- {dstack-0.18.44.dist-info → dstack-0.19.0rc1.dist-info}/entry_points.txt +0 -0
- {dstack-0.18.44.dist-info → dstack-0.19.0rc1.dist-info}/top_level.txt +0 -0
|
@@ -8,20 +8,25 @@ from pydantic import ValidationError
|
|
|
8
8
|
|
|
9
9
|
import dstack._internal.core.backends.aws.resources as aws_resources
|
|
10
10
|
from dstack._internal import settings
|
|
11
|
-
from dstack._internal.core.backends.aws.
|
|
11
|
+
from dstack._internal.core.backends.aws.models import AWSAccessKeyCreds, AWSConfig
|
|
12
12
|
from dstack._internal.core.backends.base.compute import (
|
|
13
13
|
Compute,
|
|
14
|
+
ComputeWithCreateInstanceSupport,
|
|
15
|
+
ComputeWithGatewaySupport,
|
|
16
|
+
ComputeWithMultinodeSupport,
|
|
17
|
+
ComputeWithPlacementGroupSupport,
|
|
18
|
+
ComputeWithPrivateGatewaySupport,
|
|
19
|
+
ComputeWithReservationSupport,
|
|
20
|
+
ComputeWithVolumeSupport,
|
|
14
21
|
generate_unique_gateway_instance_name,
|
|
15
22
|
generate_unique_instance_name,
|
|
16
23
|
generate_unique_volume_name,
|
|
17
24
|
get_gateway_user_data,
|
|
18
|
-
get_job_instance_name,
|
|
19
25
|
get_user_data,
|
|
20
26
|
merge_tags,
|
|
21
27
|
)
|
|
22
28
|
from dstack._internal.core.backends.base.offers import get_catalog_offers
|
|
23
29
|
from dstack._internal.core.errors import ComputeError, NoCapacityError, PlacementGroupInUseError
|
|
24
|
-
from dstack._internal.core.models.backends.aws import AWSAccessKeyCreds
|
|
25
30
|
from dstack._internal.core.models.backends.base import BackendType
|
|
26
31
|
from dstack._internal.core.models.common import CoreModel, is_core_model_instance
|
|
27
32
|
from dstack._internal.core.models.gateways import (
|
|
@@ -33,11 +38,10 @@ from dstack._internal.core.models.instances import (
|
|
|
33
38
|
InstanceConfiguration,
|
|
34
39
|
InstanceOffer,
|
|
35
40
|
InstanceOfferWithAvailability,
|
|
36
|
-
SSHKey,
|
|
37
41
|
)
|
|
38
42
|
from dstack._internal.core.models.placement import PlacementGroup, PlacementGroupProvisioningData
|
|
39
43
|
from dstack._internal.core.models.resources import Memory, Range
|
|
40
|
-
from dstack._internal.core.models.runs import
|
|
44
|
+
from dstack._internal.core.models.runs import JobProvisioningData, Requirements
|
|
41
45
|
from dstack._internal.core.models.volumes import (
|
|
42
46
|
Volume,
|
|
43
47
|
VolumeAttachmentData,
|
|
@@ -62,7 +66,16 @@ class AWSVolumeBackendData(CoreModel):
|
|
|
62
66
|
iops: int
|
|
63
67
|
|
|
64
68
|
|
|
65
|
-
class AWSCompute(
|
|
69
|
+
class AWSCompute(
|
|
70
|
+
ComputeWithCreateInstanceSupport,
|
|
71
|
+
ComputeWithMultinodeSupport,
|
|
72
|
+
ComputeWithReservationSupport,
|
|
73
|
+
ComputeWithPlacementGroupSupport,
|
|
74
|
+
ComputeWithGatewaySupport,
|
|
75
|
+
ComputeWithPrivateGatewaySupport,
|
|
76
|
+
ComputeWithVolumeSupport,
|
|
77
|
+
Compute,
|
|
78
|
+
):
|
|
66
79
|
def __init__(self, config: AWSConfig):
|
|
67
80
|
super().__init__()
|
|
68
81
|
self.config = config
|
|
@@ -270,44 +283,6 @@ class AWSCompute(Compute):
|
|
|
270
283
|
continue
|
|
271
284
|
raise NoCapacityError()
|
|
272
285
|
|
|
273
|
-
def run_job(
|
|
274
|
-
self,
|
|
275
|
-
run: Run,
|
|
276
|
-
job: Job,
|
|
277
|
-
instance_offer: InstanceOfferWithAvailability,
|
|
278
|
-
project_ssh_public_key: str,
|
|
279
|
-
project_ssh_private_key: str,
|
|
280
|
-
volumes: List[Volume],
|
|
281
|
-
) -> JobProvisioningData:
|
|
282
|
-
# TODO: run_job is the same for vm-based backends, refactor
|
|
283
|
-
instance_config = InstanceConfiguration(
|
|
284
|
-
project_name=run.project_name,
|
|
285
|
-
instance_name=get_job_instance_name(run, job), # TODO: generate name
|
|
286
|
-
ssh_keys=[
|
|
287
|
-
SSHKey(public=project_ssh_public_key.strip()),
|
|
288
|
-
],
|
|
289
|
-
user=run.user,
|
|
290
|
-
volumes=volumes,
|
|
291
|
-
reservation=run.run_spec.configuration.reservation,
|
|
292
|
-
)
|
|
293
|
-
instance_offer = instance_offer.copy()
|
|
294
|
-
if len(volumes) > 0:
|
|
295
|
-
volume = volumes[0]
|
|
296
|
-
if (
|
|
297
|
-
volume.provisioning_data is not None
|
|
298
|
-
and volume.provisioning_data.availability_zone is not None
|
|
299
|
-
):
|
|
300
|
-
if instance_offer.availability_zones is None:
|
|
301
|
-
instance_offer.availability_zones = [
|
|
302
|
-
volume.provisioning_data.availability_zone
|
|
303
|
-
]
|
|
304
|
-
instance_offer.availability_zones = [
|
|
305
|
-
z
|
|
306
|
-
for z in instance_offer.availability_zones
|
|
307
|
-
if z == volume.provisioning_data.availability_zone
|
|
308
|
-
]
|
|
309
|
-
return self.create_instance(instance_offer, instance_config)
|
|
310
|
-
|
|
311
286
|
def create_placement_group(
|
|
312
287
|
self,
|
|
313
288
|
placement_group: PlacementGroup,
|
|
@@ -382,7 +357,7 @@ class AWSCompute(Compute):
|
|
|
382
357
|
**aws_resources.create_instances_struct(
|
|
383
358
|
disk_size=10,
|
|
384
359
|
image_id=aws_resources.get_gateway_image_id(ec2_client),
|
|
385
|
-
instance_type="
|
|
360
|
+
instance_type="t3.micro",
|
|
386
361
|
iam_instance_profile=None,
|
|
387
362
|
user_data=get_gateway_user_data(configuration.ssh_key_pub),
|
|
388
363
|
tags=tags,
|
dstack/_internal/{server/services/backends/configurators/aws.py → core/backends/aws/configurator.py}
RENAMED
|
@@ -1,41 +1,35 @@
|
|
|
1
1
|
import concurrent.futures
|
|
2
2
|
import json
|
|
3
|
-
from typing import List
|
|
4
3
|
|
|
5
4
|
import botocore.exceptions
|
|
6
5
|
from boto3.session import Session
|
|
7
6
|
|
|
8
|
-
from dstack._internal.core.backends.aws import
|
|
9
|
-
from dstack._internal.core.backends.aws.
|
|
10
|
-
from dstack._internal.core.
|
|
11
|
-
|
|
12
|
-
BackendError,
|
|
13
|
-
ServerClientError,
|
|
14
|
-
)
|
|
15
|
-
from dstack._internal.core.models.backends.aws import (
|
|
16
|
-
AnyAWSConfigInfo,
|
|
7
|
+
from dstack._internal.core.backends.aws import auth, compute, resources
|
|
8
|
+
from dstack._internal.core.backends.aws.backend import AWSBackend
|
|
9
|
+
from dstack._internal.core.backends.aws.models import (
|
|
10
|
+
AnyAWSBackendConfig,
|
|
17
11
|
AWSAccessKeyCreds,
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
AWSConfigValues,
|
|
12
|
+
AWSBackendConfig,
|
|
13
|
+
AWSBackendConfigWithCreds,
|
|
14
|
+
AWSConfig,
|
|
22
15
|
AWSCreds,
|
|
23
16
|
AWSDefaultCreds,
|
|
24
17
|
AWSStoredConfig,
|
|
25
18
|
)
|
|
26
|
-
from dstack._internal.core.
|
|
27
|
-
BackendType,
|
|
28
|
-
ConfigElementValue,
|
|
29
|
-
ConfigMultiElement,
|
|
30
|
-
)
|
|
31
|
-
from dstack._internal.core.models.common import is_core_model_instance
|
|
32
|
-
from dstack._internal.server import settings
|
|
33
|
-
from dstack._internal.server.models import BackendModel, DecryptedString, ProjectModel
|
|
34
|
-
from dstack._internal.server.services.backends.configurators.base import (
|
|
19
|
+
from dstack._internal.core.backends.base.configurator import (
|
|
35
20
|
TAGS_MAX_NUM,
|
|
21
|
+
BackendRecord,
|
|
36
22
|
Configurator,
|
|
37
23
|
raise_invalid_credentials_error,
|
|
38
24
|
)
|
|
25
|
+
from dstack._internal.core.errors import (
|
|
26
|
+
BackendError,
|
|
27
|
+
ServerClientError,
|
|
28
|
+
)
|
|
29
|
+
from dstack._internal.core.models.backends.base import (
|
|
30
|
+
BackendType,
|
|
31
|
+
)
|
|
32
|
+
from dstack._internal.core.models.common import is_core_model_instance
|
|
39
33
|
from dstack._internal.utils.logging import get_logger
|
|
40
34
|
|
|
41
35
|
logger = get_logger(__name__)
|
|
@@ -59,33 +53,11 @@ MAIN_REGION = "us-east-1"
|
|
|
59
53
|
|
|
60
54
|
|
|
61
55
|
class AWSConfigurator(Configurator):
|
|
62
|
-
TYPE
|
|
56
|
+
TYPE = BackendType.AWS
|
|
57
|
+
BACKEND_CLASS = AWSBackend
|
|
63
58
|
|
|
64
|
-
def
|
|
65
|
-
if not
|
|
66
|
-
return []
|
|
67
|
-
try:
|
|
68
|
-
auth.authenticate(creds=AWSDefaultCreds(), region=MAIN_REGION)
|
|
69
|
-
except BackendAuthError:
|
|
70
|
-
return []
|
|
71
|
-
return [
|
|
72
|
-
AWSConfigInfoWithCreds(
|
|
73
|
-
regions=DEFAULT_REGIONS,
|
|
74
|
-
creds=AWSDefaultCreds(),
|
|
75
|
-
)
|
|
76
|
-
]
|
|
77
|
-
|
|
78
|
-
def get_config_values(self, config: AWSConfigInfoWithCredsPartial) -> AWSConfigValues:
|
|
79
|
-
config_values = AWSConfigValues(regions=None)
|
|
80
|
-
config_values.default_creds = (
|
|
81
|
-
settings.DEFAULT_CREDS_ENABLED and auth.default_creds_available()
|
|
82
|
-
)
|
|
83
|
-
if config.creds is None:
|
|
84
|
-
return config_values
|
|
85
|
-
if (
|
|
86
|
-
is_core_model_instance(config.creds, AWSDefaultCreds)
|
|
87
|
-
and not settings.DEFAULT_CREDS_ENABLED
|
|
88
|
-
):
|
|
59
|
+
def validate_config(self, config: AWSBackendConfigWithCreds, default_creds_enabled: bool):
|
|
60
|
+
if is_core_model_instance(config.creds, AWSDefaultCreds) and not default_creds_enabled:
|
|
89
61
|
raise_invalid_credentials_error(fields=[["creds"]])
|
|
90
62
|
try:
|
|
91
63
|
session = auth.authenticate(creds=config.creds, region=MAIN_REGION)
|
|
@@ -99,52 +71,41 @@ class AWSConfigurator(Configurator):
|
|
|
99
71
|
)
|
|
100
72
|
else:
|
|
101
73
|
raise_invalid_credentials_error(fields=[["creds"]])
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
)
|
|
105
|
-
self._check_config(session=session, config=config)
|
|
106
|
-
return config_values
|
|
74
|
+
self._check_config_tags(config)
|
|
75
|
+
self._check_config_iam_instance_profile(session, config)
|
|
76
|
+
self._check_config_vpc(session, config)
|
|
107
77
|
|
|
108
78
|
def create_backend(
|
|
109
|
-
self,
|
|
110
|
-
) ->
|
|
79
|
+
self, project_name: str, config: AWSBackendConfigWithCreds
|
|
80
|
+
) -> BackendRecord:
|
|
111
81
|
if config.regions is None:
|
|
112
82
|
config.regions = DEFAULT_REGIONS
|
|
113
|
-
return
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
auth=
|
|
83
|
+
return BackendRecord(
|
|
84
|
+
config=AWSStoredConfig(
|
|
85
|
+
**AWSBackendConfig.__response__.parse_obj(config).dict()
|
|
86
|
+
).json(),
|
|
87
|
+
auth=AWSCreds.parse_obj(config.creds).json(),
|
|
118
88
|
)
|
|
119
89
|
|
|
120
|
-
def
|
|
121
|
-
|
|
90
|
+
def get_backend_config(
|
|
91
|
+
self, record: BackendRecord, include_creds: bool
|
|
92
|
+
) -> AnyAWSBackendConfig:
|
|
93
|
+
config = self._get_config(record)
|
|
122
94
|
if include_creds:
|
|
123
|
-
return
|
|
124
|
-
return
|
|
95
|
+
return AWSBackendConfigWithCreds.__response__.parse_obj(config)
|
|
96
|
+
return AWSBackendConfig.__response__.parse_obj(config)
|
|
125
97
|
|
|
126
|
-
def get_backend(self,
|
|
127
|
-
config = self.
|
|
98
|
+
def get_backend(self, record: BackendRecord) -> AWSBackend:
|
|
99
|
+
config = self._get_config(record)
|
|
128
100
|
return AWSBackend(config=config)
|
|
129
101
|
|
|
130
|
-
def
|
|
102
|
+
def _get_config(self, record: BackendRecord) -> AWSConfig:
|
|
131
103
|
return AWSConfig.__response__(
|
|
132
|
-
**json.loads(
|
|
133
|
-
creds=AWSCreds.parse_raw(
|
|
104
|
+
**json.loads(record.config),
|
|
105
|
+
creds=AWSCreds.parse_raw(record.auth).__root__,
|
|
134
106
|
)
|
|
135
107
|
|
|
136
|
-
def
|
|
137
|
-
element = ConfigMultiElement(selected=selected)
|
|
138
|
-
for r in REGION_VALUES:
|
|
139
|
-
element.values.append(ConfigElementValue(value=r, label=r))
|
|
140
|
-
return element
|
|
141
|
-
|
|
142
|
-
def _check_config(self, session: Session, config: AWSConfigInfoWithCredsPartial):
|
|
143
|
-
self._check_tags_config(config)
|
|
144
|
-
self._check_iam_instance_profile_config(session, config)
|
|
145
|
-
self._check_vpc_config(session, config)
|
|
146
|
-
|
|
147
|
-
def _check_tags_config(self, config: AWSConfigInfoWithCredsPartial):
|
|
108
|
+
def _check_config_tags(self, config: AWSBackendConfigWithCreds):
|
|
148
109
|
if not config.tags:
|
|
149
110
|
return
|
|
150
111
|
if len(config.tags) > TAGS_MAX_NUM:
|
|
@@ -156,8 +117,8 @@ class AWSConfigurator(Configurator):
|
|
|
156
117
|
except BackendError as e:
|
|
157
118
|
raise ServerClientError(e.args[0])
|
|
158
119
|
|
|
159
|
-
def
|
|
160
|
-
self, session: Session, config:
|
|
120
|
+
def _check_config_iam_instance_profile(
|
|
121
|
+
self, session: Session, config: AWSBackendConfigWithCreds
|
|
161
122
|
):
|
|
162
123
|
if config.iam_instance_profile is None:
|
|
163
124
|
return
|
|
@@ -181,7 +142,7 @@ class AWSConfigurator(Configurator):
|
|
|
181
142
|
f"Failed to check IAM instance profile {config.iam_instance_profile}"
|
|
182
143
|
)
|
|
183
144
|
|
|
184
|
-
def
|
|
145
|
+
def _check_config_vpc(self, session: Session, config: AWSBackendConfigWithCreds):
|
|
185
146
|
allocate_public_ip = config.public_ips if config.public_ips is not None else True
|
|
186
147
|
use_default_vpcs = config.default_vpcs if config.default_vpcs is not None else True
|
|
187
148
|
if config.vpc_name is not None and config.vpc_ids is not None:
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
from typing import Annotated, Dict, List, Literal, Optional, Union
|
|
2
|
+
|
|
3
|
+
from pydantic import Field
|
|
4
|
+
|
|
5
|
+
from dstack._internal.core.models.common import CoreModel
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class AWSOSImage(CoreModel):
|
|
9
|
+
name: Annotated[str, Field(description="The AMI name")]
|
|
10
|
+
owner: Annotated[
|
|
11
|
+
str,
|
|
12
|
+
Field(regex=r"^(\d{12}|self)$", description="The AMI owner, account ID or `self`"),
|
|
13
|
+
] = "self"
|
|
14
|
+
user: Annotated[str, Field(description="The OS user for provisioning")]
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class AWSOSImageConfig(CoreModel):
|
|
18
|
+
cpu: Annotated[Optional[AWSOSImage], Field(description="The AMI used for CPU instances")] = (
|
|
19
|
+
None
|
|
20
|
+
)
|
|
21
|
+
nvidia: Annotated[
|
|
22
|
+
Optional[AWSOSImage], Field(description="The AMI used for NVIDIA GPU instances")
|
|
23
|
+
] = None
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class AWSAccessKeyCreds(CoreModel):
|
|
27
|
+
type: Annotated[Literal["access_key"], Field(description="The type of credentials")] = (
|
|
28
|
+
"access_key"
|
|
29
|
+
)
|
|
30
|
+
access_key: Annotated[str, Field(description="The access key")]
|
|
31
|
+
secret_key: Annotated[str, Field(description="The secret key")]
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class AWSDefaultCreds(CoreModel):
|
|
35
|
+
type: Annotated[Literal["default"], Field(description="The type of credentials")] = "default"
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
AnyAWSCreds = Union[AWSAccessKeyCreds, AWSDefaultCreds]
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class AWSCreds(CoreModel):
|
|
42
|
+
__root__: AnyAWSCreds = Field(..., discriminator="type")
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class AWSBackendConfig(CoreModel):
|
|
46
|
+
type: Annotated[Literal["aws"], Field(description="The type of the backend")] = "aws"
|
|
47
|
+
regions: Annotated[
|
|
48
|
+
Optional[List[str]], Field(description="The list of AWS regions. Omit to use all regions")
|
|
49
|
+
] = None
|
|
50
|
+
vpc_name: Annotated[
|
|
51
|
+
Optional[str],
|
|
52
|
+
Field(
|
|
53
|
+
description=(
|
|
54
|
+
"The name of custom VPCs. All configured regions must have a VPC with this name."
|
|
55
|
+
" If your custom VPCs don't have names or have different names in different regions, use `vpc_ids` instead."
|
|
56
|
+
)
|
|
57
|
+
),
|
|
58
|
+
] = None
|
|
59
|
+
vpc_ids: Annotated[
|
|
60
|
+
Optional[Dict[str, str]],
|
|
61
|
+
Field(
|
|
62
|
+
description=(
|
|
63
|
+
"The mapping from AWS regions to VPC IDs."
|
|
64
|
+
" If `default_vpcs: true`, omitted regions will use default VPCs"
|
|
65
|
+
)
|
|
66
|
+
),
|
|
67
|
+
] = None
|
|
68
|
+
default_vpcs: Annotated[
|
|
69
|
+
Optional[bool],
|
|
70
|
+
Field(
|
|
71
|
+
description=(
|
|
72
|
+
"A flag to enable/disable using default VPCs in regions not configured by `vpc_ids`."
|
|
73
|
+
" Set to `false` if default VPCs should never be used."
|
|
74
|
+
" Defaults to `true`"
|
|
75
|
+
)
|
|
76
|
+
),
|
|
77
|
+
] = None
|
|
78
|
+
public_ips: Annotated[
|
|
79
|
+
Optional[bool],
|
|
80
|
+
Field(
|
|
81
|
+
description=(
|
|
82
|
+
"A flag to enable/disable public IP assigning on instances."
|
|
83
|
+
" `public_ips: false` requires at least one private subnet with outbound internet connectivity"
|
|
84
|
+
" provided by a NAT Gateway or a Transit Gateway."
|
|
85
|
+
" Defaults to `true`"
|
|
86
|
+
)
|
|
87
|
+
),
|
|
88
|
+
] = None
|
|
89
|
+
iam_instance_profile: Annotated[
|
|
90
|
+
Optional[str],
|
|
91
|
+
Field(
|
|
92
|
+
description=(
|
|
93
|
+
"The name of the IAM instance profile to associate with EC2 instances."
|
|
94
|
+
" You can also specify the IAM role name for roles created via the AWS console."
|
|
95
|
+
" AWS automatically creates an instance profile and gives it the same name as the role"
|
|
96
|
+
)
|
|
97
|
+
),
|
|
98
|
+
] = None
|
|
99
|
+
tags: Annotated[
|
|
100
|
+
Optional[Dict[str, str]],
|
|
101
|
+
Field(description="The tags that will be assigned to resources created by `dstack`"),
|
|
102
|
+
] = None
|
|
103
|
+
os_images: Annotated[
|
|
104
|
+
Optional[AWSOSImageConfig],
|
|
105
|
+
Field(
|
|
106
|
+
description="The mapping of instance categories (CPU, NVIDIA GPU) to AMI configurations"
|
|
107
|
+
),
|
|
108
|
+
] = None
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
class AWSBackendConfigWithCreds(AWSBackendConfig):
|
|
112
|
+
creds: AnyAWSCreds = Field(..., description="The credentials", discriminator="type")
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
AnyAWSBackendConfig = Union[AWSBackendConfig, AWSBackendConfigWithCreds]
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
class AWSStoredConfig(AWSBackendConfig):
|
|
119
|
+
pass
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
class AWSConfig(AWSStoredConfig):
|
|
123
|
+
creds: AnyAWSCreds
|
|
124
|
+
|
|
125
|
+
@property
|
|
126
|
+
def allocate_public_ips(self) -> bool:
|
|
127
|
+
if self.public_ips is not None:
|
|
128
|
+
return self.public_ips
|
|
129
|
+
return True
|
|
130
|
+
|
|
131
|
+
@property
|
|
132
|
+
def use_default_vpcs(self) -> bool:
|
|
133
|
+
if self.default_vpcs is not None:
|
|
134
|
+
return self.default_vpcs
|
|
135
|
+
return True
|
|
@@ -5,8 +5,8 @@ import botocore.client
|
|
|
5
5
|
import botocore.exceptions
|
|
6
6
|
|
|
7
7
|
import dstack.version as version
|
|
8
|
+
from dstack._internal.core.backends.aws.models import AWSOSImageConfig
|
|
8
9
|
from dstack._internal.core.errors import BackendError, ComputeError, ComputeResourceNotFoundError
|
|
9
|
-
from dstack._internal.core.models.backends.aws import AWSOSImageConfig
|
|
10
10
|
from dstack._internal.utils.logging import get_logger
|
|
11
11
|
|
|
12
12
|
logger = get_logger(__name__)
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
from dstack._internal.core.backends.azure import auth
|
|
2
|
-
from dstack._internal.core.backends.azure.compute import AzureCompute
|
|
3
|
-
from dstack._internal.core.backends.azure.config import AzureConfig
|
|
4
|
-
from dstack._internal.core.backends.base import Backend
|
|
5
|
-
from dstack._internal.core.models.backends.base import BackendType
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
class AzureBackend(Backend):
|
|
9
|
-
TYPE: BackendType = BackendType.AZURE
|
|
10
|
-
|
|
11
|
-
def __init__(self, config: AzureConfig):
|
|
12
|
-
self.config = config
|
|
13
|
-
self.credential, _ = auth.authenticate(self.config.creds)
|
|
14
|
-
self._compute = AzureCompute(
|
|
15
|
-
config=self.config,
|
|
16
|
-
credential=self.credential,
|
|
17
|
-
)
|
|
18
|
-
|
|
19
|
-
def compute(self) -> AzureCompute:
|
|
20
|
-
return self._compute
|
|
@@ -4,12 +4,11 @@ from azure.core.exceptions import ClientAuthenticationError
|
|
|
4
4
|
from azure.identity import ClientSecretCredential, DefaultAzureCredential
|
|
5
5
|
from azure.mgmt.subscription import SubscriptionClient
|
|
6
6
|
|
|
7
|
-
from dstack._internal.core.
|
|
8
|
-
from dstack._internal.core.models.backends.azure import (
|
|
7
|
+
from dstack._internal.core.backends.azure.models import (
|
|
9
8
|
AnyAzureCreds,
|
|
10
9
|
AzureClientCreds,
|
|
11
|
-
AzureDefaultCreds,
|
|
12
10
|
)
|
|
11
|
+
from dstack._internal.core.errors import BackendAuthError
|
|
13
12
|
from dstack._internal.core.models.common import is_core_model_instance
|
|
14
13
|
|
|
15
14
|
AzureCredential = Union[ClientSecretCredential, DefaultAzureCredential]
|
|
@@ -39,11 +38,3 @@ def check_credential(credential: AzureCredential):
|
|
|
39
38
|
list(client.subscriptions.list())
|
|
40
39
|
except ClientAuthenticationError:
|
|
41
40
|
raise BackendAuthError()
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
def default_creds_available() -> bool:
|
|
45
|
-
try:
|
|
46
|
-
authenticate(AzureDefaultCreds())
|
|
47
|
-
except BackendAuthError:
|
|
48
|
-
return False
|
|
49
|
-
return True
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
from dstack._internal.core.backends.azure import auth
|
|
2
|
+
from dstack._internal.core.backends.azure.compute import AzureCompute
|
|
3
|
+
from dstack._internal.core.backends.azure.models import AzureConfig
|
|
4
|
+
from dstack._internal.core.backends.base.backend import Backend
|
|
5
|
+
from dstack._internal.core.models.backends.base import BackendType
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class AzureBackend(Backend):
|
|
9
|
+
TYPE = BackendType.AZURE
|
|
10
|
+
COMPUTE_CLASS = AzureCompute
|
|
11
|
+
|
|
12
|
+
def __init__(self, config: AzureConfig):
|
|
13
|
+
self.config = config
|
|
14
|
+
self.credential, _ = auth.authenticate(self.config.creds)
|
|
15
|
+
self._compute = AzureCompute(
|
|
16
|
+
config=self.config,
|
|
17
|
+
credential=self.credential,
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
def compute(self) -> AzureCompute:
|
|
21
|
+
return self._compute
|
|
@@ -36,13 +36,15 @@ from dstack import version
|
|
|
36
36
|
from dstack._internal import settings
|
|
37
37
|
from dstack._internal.core.backends.azure import resources as azure_resources
|
|
38
38
|
from dstack._internal.core.backends.azure import utils as azure_utils
|
|
39
|
-
from dstack._internal.core.backends.azure.
|
|
39
|
+
from dstack._internal.core.backends.azure.models import AzureConfig
|
|
40
40
|
from dstack._internal.core.backends.base.compute import (
|
|
41
41
|
Compute,
|
|
42
|
+
ComputeWithCreateInstanceSupport,
|
|
43
|
+
ComputeWithGatewaySupport,
|
|
44
|
+
ComputeWithMultinodeSupport,
|
|
42
45
|
generate_unique_gateway_instance_name,
|
|
43
46
|
generate_unique_instance_name,
|
|
44
47
|
get_gateway_user_data,
|
|
45
|
-
get_job_instance_name,
|
|
46
48
|
get_user_data,
|
|
47
49
|
merge_tags,
|
|
48
50
|
)
|
|
@@ -59,11 +61,9 @@ from dstack._internal.core.models.instances import (
|
|
|
59
61
|
InstanceOffer,
|
|
60
62
|
InstanceOfferWithAvailability,
|
|
61
63
|
InstanceType,
|
|
62
|
-
SSHKey,
|
|
63
64
|
)
|
|
64
65
|
from dstack._internal.core.models.resources import Memory, Range
|
|
65
|
-
from dstack._internal.core.models.runs import
|
|
66
|
-
from dstack._internal.core.models.volumes import Volume
|
|
66
|
+
from dstack._internal.core.models.runs import JobProvisioningData, Requirements
|
|
67
67
|
from dstack._internal.utils.logging import get_logger
|
|
68
68
|
|
|
69
69
|
logger = get_logger(__name__)
|
|
@@ -71,7 +71,12 @@ logger = get_logger(__name__)
|
|
|
71
71
|
CONFIGURABLE_DISK_SIZE = Range[Memory](min=Memory.parse("30GB"), max=Memory.parse("4095GB"))
|
|
72
72
|
|
|
73
73
|
|
|
74
|
-
class AzureCompute(
|
|
74
|
+
class AzureCompute(
|
|
75
|
+
ComputeWithCreateInstanceSupport,
|
|
76
|
+
ComputeWithMultinodeSupport,
|
|
77
|
+
ComputeWithGatewaySupport,
|
|
78
|
+
Compute,
|
|
79
|
+
):
|
|
75
80
|
def __init__(self, config: AzureConfig, credential: TokenCredential):
|
|
76
81
|
super().__init__()
|
|
77
82
|
self.config = config
|
|
@@ -88,14 +93,14 @@ class AzureCompute(Compute):
|
|
|
88
93
|
) -> List[InstanceOfferWithAvailability]:
|
|
89
94
|
offers = get_catalog_offers(
|
|
90
95
|
backend=BackendType.AZURE,
|
|
91
|
-
locations=self.config.
|
|
96
|
+
locations=self.config.regions,
|
|
92
97
|
requirements=requirements,
|
|
93
98
|
configurable_disk_size=CONFIGURABLE_DISK_SIZE,
|
|
94
99
|
extra_filter=_supported_instances,
|
|
95
100
|
)
|
|
96
101
|
offers_with_availability = _get_offers_with_availability(
|
|
97
102
|
compute_client=self._compute_client,
|
|
98
|
-
config_locations=self.config.
|
|
103
|
+
config_locations=self.config.regions,
|
|
99
104
|
offers=offers,
|
|
100
105
|
)
|
|
101
106
|
return offers_with_availability
|
|
@@ -190,25 +195,6 @@ class AzureCompute(Compute):
|
|
|
190
195
|
backend_data=None,
|
|
191
196
|
)
|
|
192
197
|
|
|
193
|
-
def run_job(
|
|
194
|
-
self,
|
|
195
|
-
run: Run,
|
|
196
|
-
job: Job,
|
|
197
|
-
instance_offer: InstanceOfferWithAvailability,
|
|
198
|
-
project_ssh_public_key: str,
|
|
199
|
-
project_ssh_private_key: str,
|
|
200
|
-
volumes: List[Volume],
|
|
201
|
-
) -> JobProvisioningData:
|
|
202
|
-
instance_config = InstanceConfiguration(
|
|
203
|
-
project_name=run.project_name,
|
|
204
|
-
instance_name=get_job_instance_name(run, job), # TODO: generate name
|
|
205
|
-
ssh_keys=[
|
|
206
|
-
SSHKey(public=project_ssh_public_key.strip()),
|
|
207
|
-
],
|
|
208
|
-
user=run.user,
|
|
209
|
-
)
|
|
210
|
-
return self.create_instance(instance_offer, instance_config)
|
|
211
|
-
|
|
212
198
|
def terminate_instance(
|
|
213
199
|
self, instance_id: str, region: str, backend_data: Optional[str] = None
|
|
214
200
|
):
|