dstack 0.18.43__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 -20
- dstack/_internal/cli/services/profile.py +34 -83
- dstack/_internal/cli/utils/gateway.py +1 -1
- dstack/_internal/cli/utils/run.py +11 -0
- 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 +21 -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 +14 -28
- 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 +14 -44
- 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 +28 -6
- 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 +22 -16
- 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 +85 -45
- 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 +21 -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 +11 -4
- dstack/_internal/server/background/__init__.py +10 -0
- 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 +5 -1
- dstack/_internal/server/background/tasks/process_prometheus_metrics.py +135 -0
- dstack/_internal/server/background/tasks/process_running_jobs.py +80 -24
- dstack/_internal/server/background/tasks/process_runs.py +1 -0
- dstack/_internal/server/background/tasks/process_submitted_jobs.py +20 -38
- dstack/_internal/server/background/tasks/process_volumes.py +5 -2
- dstack/_internal/server/migrations/versions/60e444118b6d_add_jobprometheusmetrics.py +40 -0
- dstack/_internal/server/migrations/versions/7bc2586e8b9e_make_instancemodel_pool_id_optional.py +36 -0
- dstack/_internal/server/migrations/versions/98d1b92988bc_add_jobterminationreason_terminated_due_.py +140 -0
- dstack/_internal/server/migrations/versions/bc8ca4a505c6_store_backendtype_as_string.py +171 -0
- dstack/_internal/server/models.py +59 -9
- dstack/_internal/server/routers/backends.py +14 -23
- dstack/_internal/server/routers/instances.py +3 -4
- dstack/_internal/server/routers/metrics.py +31 -10
- dstack/_internal/server/routers/prometheus.py +36 -0
- 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/security/permissions.py +1 -1
- dstack/_internal/server/services/backends/__init__.py +85 -158
- dstack/_internal/server/services/config.py +53 -567
- dstack/_internal/server/services/fleets.py +9 -103
- dstack/_internal/server/services/gateways/__init__.py +13 -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 +25 -1
- 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 +131 -72
- dstack/_internal/server/services/offers.py +1 -1
- dstack/_internal/server/services/projects.py +23 -14
- dstack/_internal/server/services/prometheus.py +245 -0
- dstack/_internal/server/services/runner/client.py +14 -3
- dstack/_internal/server/services/runs.py +67 -31
- dstack/_internal/server/services/volumes.py +9 -4
- dstack/_internal/server/settings.py +3 -0
- dstack/_internal/server/statics/index.html +1 -1
- dstack/_internal/server/statics/{main-fe8fd9db55df8d10e648.js → main-4fd5a4770eff59325ee3.js} +68 -15
- dstack/_internal/server/statics/{main-fe8fd9db55df8d10e648.js.map → main-4fd5a4770eff59325ee3.js.map} +1 -1
- dstack/_internal/server/statics/{main-7510e71dfa9749a4e70e.css → main-da9f8c06a69c20dac23e.css} +1 -1
- dstack/_internal/server/statics/static/media/entraID.d65d1f3e9486a8e56d24fc07b3230885.svg +9 -0
- dstack/_internal/server/testing/common.py +75 -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 +170 -83
- dstack/api/server/__init__.py +11 -13
- dstack/api/server/_backends.py +12 -16
- dstack/api/server/_fleets.py +15 -55
- dstack/api/server/_gateways.py +3 -14
- dstack/api/server/_repos.py +1 -4
- dstack/api/server/_runs.py +21 -96
- dstack/api/server/_volumes.py +10 -5
- dstack/api/utils.py +3 -0
- dstack/version.py +1 -1
- {dstack-0.18.43.dist-info → dstack-0.19.0rc1.dist-info}/METADATA +10 -1
- {dstack-0.18.43.dist-info → dstack-0.19.0rc1.dist-info}/RECORD +229 -206
- 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 +186 -0
- tests/_internal/server/background/tasks/test_process_running_jobs.py +123 -19
- 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 +2 -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 +42 -0
- tests/_internal/server/routers/test_projects.py +56 -0
- tests/_internal/server/routers/test_prometheus.py +333 -0
- tests/_internal/server/routers/test_repos.py +0 -15
- tests/_internal/server/routers/test_runs.py +83 -275
- 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 +167 -0
- 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 -9
- 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 -40
- 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 -97
- 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.43.dist-info → dstack-0.19.0rc1.dist-info}/LICENSE.md +0 -0
- {dstack-0.18.43.dist-info → dstack-0.19.0rc1.dist-info}/WHEEL +0 -0
- {dstack-0.18.43.dist-info → dstack-0.19.0rc1.dist-info}/entry_points.txt +0 -0
- {dstack-0.18.43.dist-info → dstack-0.19.0rc1.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import json
|
|
2
|
+
|
|
3
|
+
from dstack._internal.core.backends.base.configurator import (
|
|
4
|
+
BackendRecord,
|
|
5
|
+
Configurator,
|
|
6
|
+
raise_invalid_credentials_error,
|
|
7
|
+
)
|
|
8
|
+
from dstack._internal.core.backends.lambdalabs import api_client
|
|
9
|
+
from dstack._internal.core.backends.lambdalabs.backend import LambdaBackend
|
|
10
|
+
from dstack._internal.core.backends.lambdalabs.models import (
|
|
11
|
+
AnyLambdaBackendConfig,
|
|
12
|
+
LambdaBackendConfig,
|
|
13
|
+
LambdaBackendConfigWithCreds,
|
|
14
|
+
LambdaConfig,
|
|
15
|
+
LambdaCreds,
|
|
16
|
+
LambdaStoredConfig,
|
|
17
|
+
)
|
|
18
|
+
from dstack._internal.core.models.backends.base import (
|
|
19
|
+
BackendType,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
REGIONS = [
|
|
23
|
+
"us-south-1",
|
|
24
|
+
"us-south-2",
|
|
25
|
+
"us-south-3",
|
|
26
|
+
"us-west-2",
|
|
27
|
+
"us-west-1",
|
|
28
|
+
"us-midwest-1",
|
|
29
|
+
"us-west-3",
|
|
30
|
+
"us-east-1",
|
|
31
|
+
"us-east-2",
|
|
32
|
+
"europe-central-1",
|
|
33
|
+
"asia-south-1",
|
|
34
|
+
"me-west-1",
|
|
35
|
+
"asia-northeast-1",
|
|
36
|
+
"asia-northeast-2",
|
|
37
|
+
]
|
|
38
|
+
|
|
39
|
+
DEFAULT_REGION = "us-east-1"
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class LambdaConfigurator(Configurator):
|
|
43
|
+
TYPE = BackendType.LAMBDA
|
|
44
|
+
BACKEND_CLASS = LambdaBackend
|
|
45
|
+
|
|
46
|
+
def validate_config(self, config: LambdaBackendConfigWithCreds, default_creds_enabled: bool):
|
|
47
|
+
self._validate_lambda_api_key(config.creds.api_key)
|
|
48
|
+
|
|
49
|
+
def create_backend(
|
|
50
|
+
self, project_name: str, config: LambdaBackendConfigWithCreds
|
|
51
|
+
) -> BackendRecord:
|
|
52
|
+
if config.regions is None:
|
|
53
|
+
config.regions = REGIONS
|
|
54
|
+
return BackendRecord(
|
|
55
|
+
config=LambdaStoredConfig(
|
|
56
|
+
**LambdaBackendConfig.__response__.parse_obj(config).dict()
|
|
57
|
+
).json(),
|
|
58
|
+
auth=LambdaCreds.parse_obj(config.creds).json(),
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
def get_backend_config(
|
|
62
|
+
self, record: BackendRecord, include_creds: bool
|
|
63
|
+
) -> AnyLambdaBackendConfig:
|
|
64
|
+
config = self._get_config(record)
|
|
65
|
+
if include_creds:
|
|
66
|
+
return LambdaBackendConfigWithCreds.__response__.parse_obj(config)
|
|
67
|
+
return LambdaBackendConfig.__response__.parse_obj(config)
|
|
68
|
+
|
|
69
|
+
def get_backend(self, record: BackendRecord) -> LambdaBackend:
|
|
70
|
+
config = self._get_config(record)
|
|
71
|
+
return LambdaBackend(config=config)
|
|
72
|
+
|
|
73
|
+
def _get_config(self, record: BackendRecord) -> LambdaConfig:
|
|
74
|
+
return LambdaConfig.__response__(
|
|
75
|
+
**json.loads(record.config),
|
|
76
|
+
creds=LambdaCreds.parse_raw(record.auth),
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
def _validate_lambda_api_key(self, api_key: str):
|
|
80
|
+
client = api_client.LambdaAPIClient(api_key=api_key)
|
|
81
|
+
if not client.validate_api_key():
|
|
82
|
+
raise_invalid_credentials_error(fields=[["creds", "api_key"]])
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
from typing import Annotated, List, Literal, Optional, Union
|
|
2
|
+
|
|
3
|
+
from pydantic import Field
|
|
4
|
+
|
|
5
|
+
from dstack._internal.core.models.common import CoreModel
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class LambdaAPIKeyCreds(CoreModel):
|
|
9
|
+
type: Annotated[Literal["api_key"], Field(description="The type of credentials")] = "api_key"
|
|
10
|
+
api_key: Annotated[str, Field(description="The API key")]
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
AnyLambdaCreds = LambdaAPIKeyCreds
|
|
14
|
+
LambdaCreds = AnyLambdaCreds
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class LambdaBackendConfig(CoreModel):
|
|
18
|
+
type: Annotated[Literal["lambda"], Field(description="The type of backend")] = "lambda"
|
|
19
|
+
regions: Annotated[
|
|
20
|
+
Optional[List[str]],
|
|
21
|
+
Field(description="The list of Lambda regions. Omit to use all regions"),
|
|
22
|
+
] = None
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class LambdaBackendConfigWithCreds(LambdaBackendConfig):
|
|
26
|
+
creds: Annotated[AnyLambdaCreds, Field(description="The credentials")]
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
AnyLambdaBackendConfig = Union[LambdaBackendConfig, LambdaBackendConfigWithCreds]
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class LambdaStoredConfig(LambdaBackendConfig):
|
|
33
|
+
pass
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class LambdaConfig(LambdaStoredConfig):
|
|
37
|
+
creds: AnyLambdaCreds
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
from dstack._internal.core.backends.base import Backend
|
|
2
|
-
from dstack._internal.core.backends.local.compute import LocalCompute
|
|
3
|
-
from dstack._internal.core.models.backends.base import BackendType
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
class LocalBackend(Backend):
|
|
7
|
-
TYPE: BackendType = BackendType.LOCAL
|
|
8
|
-
|
|
9
|
-
def __init__(self):
|
|
10
|
-
self._compute = LocalCompute()
|
|
11
|
-
|
|
12
|
-
def compute(self) -> LocalCompute:
|
|
13
|
-
return self._compute
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
from dstack._internal.core.backends.base.backend import Backend
|
|
2
|
+
from dstack._internal.core.backends.local.compute import LocalCompute
|
|
3
|
+
from dstack._internal.core.models.backends.base import BackendType
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class LocalBackend(Backend):
|
|
7
|
+
TYPE = BackendType.LOCAL
|
|
8
|
+
COMPUTE_CLASS = LocalCompute
|
|
9
|
+
|
|
10
|
+
def __init__(self):
|
|
11
|
+
self._compute = LocalCompute()
|
|
12
|
+
|
|
13
|
+
def compute(self) -> LocalCompute:
|
|
14
|
+
return self._compute
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
from typing import List, Optional
|
|
2
2
|
|
|
3
|
-
from dstack._internal.core.backends.base.compute import
|
|
3
|
+
from dstack._internal.core.backends.base.compute import (
|
|
4
|
+
Compute,
|
|
5
|
+
ComputeWithCreateInstanceSupport,
|
|
6
|
+
ComputeWithVolumeSupport,
|
|
7
|
+
)
|
|
4
8
|
from dstack._internal.core.consts import DSTACK_RUNNER_SSH_PORT
|
|
5
9
|
from dstack._internal.core.models.backends.base import BackendType
|
|
6
10
|
from dstack._internal.core.models.instances import (
|
|
@@ -18,7 +22,11 @@ from dstack._internal.utils.logging import get_logger
|
|
|
18
22
|
logger = get_logger(__name__)
|
|
19
23
|
|
|
20
24
|
|
|
21
|
-
class LocalCompute(
|
|
25
|
+
class LocalCompute(
|
|
26
|
+
ComputeWithCreateInstanceSupport,
|
|
27
|
+
ComputeWithVolumeSupport,
|
|
28
|
+
Compute,
|
|
29
|
+
):
|
|
22
30
|
def get_offers(
|
|
23
31
|
self, requirements: Optional[Requirements] = None
|
|
24
32
|
) -> List[InstanceOfferWithAvailability]:
|
|
@@ -85,6 +93,12 @@ class LocalCompute(Compute):
|
|
|
85
93
|
backend_data=None,
|
|
86
94
|
)
|
|
87
95
|
|
|
96
|
+
def register_volume(self, volume: Volume) -> VolumeProvisioningData:
|
|
97
|
+
return VolumeProvisioningData(
|
|
98
|
+
volume_id=volume.volume_id,
|
|
99
|
+
size_gb=volume.configuration.size_gb,
|
|
100
|
+
)
|
|
101
|
+
|
|
88
102
|
def create_volume(self, volume: Volume) -> VolumeProvisioningData:
|
|
89
103
|
return VolumeProvisioningData(
|
|
90
104
|
volume_id=volume.name,
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
from typing import Union
|
|
2
|
+
|
|
3
|
+
from dstack._internal.core.backends.aws.models import (
|
|
4
|
+
AWSBackendConfig,
|
|
5
|
+
AWSBackendConfigWithCreds,
|
|
6
|
+
)
|
|
7
|
+
from dstack._internal.core.backends.azure.models import (
|
|
8
|
+
AzureBackendConfig,
|
|
9
|
+
AzureBackendConfigWithCreds,
|
|
10
|
+
)
|
|
11
|
+
from dstack._internal.core.backends.cudo.models import (
|
|
12
|
+
CudoBackendConfig,
|
|
13
|
+
CudoBackendConfigWithCreds,
|
|
14
|
+
)
|
|
15
|
+
from dstack._internal.core.backends.datacrunch.models import (
|
|
16
|
+
DataCrunchBackendConfig,
|
|
17
|
+
DataCrunchBackendConfigWithCreds,
|
|
18
|
+
)
|
|
19
|
+
from dstack._internal.core.backends.dstack.models import (
|
|
20
|
+
DstackBackendConfig,
|
|
21
|
+
DstackBaseBackendConfig,
|
|
22
|
+
)
|
|
23
|
+
from dstack._internal.core.backends.gcp.models import (
|
|
24
|
+
GCPBackendConfig,
|
|
25
|
+
GCPBackendConfigWithCreds,
|
|
26
|
+
GCPBackendFileConfigWithCreds,
|
|
27
|
+
)
|
|
28
|
+
from dstack._internal.core.backends.kubernetes.models import (
|
|
29
|
+
KubernetesBackendConfig,
|
|
30
|
+
KubernetesBackendConfigWithCreds,
|
|
31
|
+
KubernetesBackendFileConfigWithCreds,
|
|
32
|
+
)
|
|
33
|
+
from dstack._internal.core.backends.lambdalabs.models import (
|
|
34
|
+
LambdaBackendConfig,
|
|
35
|
+
LambdaBackendConfigWithCreds,
|
|
36
|
+
)
|
|
37
|
+
from dstack._internal.core.backends.oci.models import (
|
|
38
|
+
OCIBackendConfig,
|
|
39
|
+
OCIBackendConfigWithCreds,
|
|
40
|
+
)
|
|
41
|
+
from dstack._internal.core.backends.runpod.models import (
|
|
42
|
+
RunpodBackendConfig,
|
|
43
|
+
RunpodBackendConfigWithCreds,
|
|
44
|
+
)
|
|
45
|
+
from dstack._internal.core.backends.tensordock.models import (
|
|
46
|
+
TensorDockBackendConfig,
|
|
47
|
+
TensorDockBackendConfigWithCreds,
|
|
48
|
+
)
|
|
49
|
+
from dstack._internal.core.backends.vastai.models import (
|
|
50
|
+
VastAIBackendConfig,
|
|
51
|
+
VastAIBackendConfigWithCreds,
|
|
52
|
+
)
|
|
53
|
+
from dstack._internal.core.backends.vultr.models import (
|
|
54
|
+
VultrBackendConfig,
|
|
55
|
+
VultrBackendConfigWithCreds,
|
|
56
|
+
)
|
|
57
|
+
from dstack._internal.core.models.common import CoreModel
|
|
58
|
+
|
|
59
|
+
# Backend config returned by the API
|
|
60
|
+
AnyBackendConfigWithoutCreds = Union[
|
|
61
|
+
AWSBackendConfig,
|
|
62
|
+
AzureBackendConfig,
|
|
63
|
+
CudoBackendConfig,
|
|
64
|
+
DataCrunchBackendConfig,
|
|
65
|
+
GCPBackendConfig,
|
|
66
|
+
KubernetesBackendConfig,
|
|
67
|
+
LambdaBackendConfig,
|
|
68
|
+
OCIBackendConfig,
|
|
69
|
+
RunpodBackendConfig,
|
|
70
|
+
TensorDockBackendConfig,
|
|
71
|
+
VastAIBackendConfig,
|
|
72
|
+
VultrBackendConfig,
|
|
73
|
+
DstackBackendConfig,
|
|
74
|
+
DstackBaseBackendConfig,
|
|
75
|
+
]
|
|
76
|
+
|
|
77
|
+
# Same as AnyBackendConfigWithoutCreds but also includes creds.
|
|
78
|
+
# Used to create/update backend.
|
|
79
|
+
# Also returned by the API to project admins so that they can see/update backend creds.
|
|
80
|
+
AnyBackendConfigWithCreds = Union[
|
|
81
|
+
AWSBackendConfigWithCreds,
|
|
82
|
+
AzureBackendConfigWithCreds,
|
|
83
|
+
CudoBackendConfigWithCreds,
|
|
84
|
+
DataCrunchBackendConfigWithCreds,
|
|
85
|
+
GCPBackendConfigWithCreds,
|
|
86
|
+
KubernetesBackendConfigWithCreds,
|
|
87
|
+
LambdaBackendConfigWithCreds,
|
|
88
|
+
OCIBackendConfigWithCreds,
|
|
89
|
+
RunpodBackendConfigWithCreds,
|
|
90
|
+
TensorDockBackendConfigWithCreds,
|
|
91
|
+
VastAIBackendConfigWithCreds,
|
|
92
|
+
VultrBackendConfigWithCreds,
|
|
93
|
+
DstackBackendConfig,
|
|
94
|
+
]
|
|
95
|
+
|
|
96
|
+
# Backend config accepted in server/config.yaml.
|
|
97
|
+
# This can be different from the API config.
|
|
98
|
+
# For example, it can make creds data optional and resolve it by filename.
|
|
99
|
+
AnyBackendFileConfigWithCreds = Union[
|
|
100
|
+
AWSBackendConfigWithCreds,
|
|
101
|
+
AzureBackendConfigWithCreds,
|
|
102
|
+
CudoBackendConfigWithCreds,
|
|
103
|
+
DataCrunchBackendConfigWithCreds,
|
|
104
|
+
GCPBackendFileConfigWithCreds,
|
|
105
|
+
KubernetesBackendFileConfigWithCreds,
|
|
106
|
+
LambdaBackendConfigWithCreds,
|
|
107
|
+
OCIBackendConfigWithCreds,
|
|
108
|
+
RunpodBackendConfigWithCreds,
|
|
109
|
+
TensorDockBackendConfigWithCreds,
|
|
110
|
+
VastAIBackendConfigWithCreds,
|
|
111
|
+
VultrBackendConfigWithCreds,
|
|
112
|
+
]
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
# The API can return backend config with or without creds
|
|
116
|
+
AnyBackendConfig = Union[AnyBackendConfigWithoutCreds, AnyBackendConfigWithCreds]
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
# In case we'll support multiple backends of the same type,
|
|
120
|
+
# this adds backend name to backend config.
|
|
121
|
+
class BackendInfo(CoreModel):
|
|
122
|
+
name: str
|
|
123
|
+
config: AnyBackendConfigWithoutCreds
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
class BackendInfoYAML(CoreModel):
|
|
127
|
+
name: str
|
|
128
|
+
config_yaml: str
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
from dstack._internal.core.backends.base import Backend
|
|
2
|
-
from dstack._internal.core.backends.oci.compute import OCICompute
|
|
3
|
-
from dstack._internal.core.backends.oci.config import OCIConfig
|
|
4
|
-
from dstack._internal.core.models.backends.base import BackendType
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
class OCIBackend(Backend):
|
|
8
|
-
TYPE: BackendType = BackendType.OCI
|
|
9
|
-
|
|
10
|
-
def __init__(self, config: OCIConfig):
|
|
11
|
-
self.config = config
|
|
12
|
-
self._compute = OCICompute(self.config)
|
|
13
|
-
|
|
14
|
-
def compute(self) -> OCICompute:
|
|
15
|
-
return self._compute
|
|
@@ -2,7 +2,7 @@ import oci
|
|
|
2
2
|
from typing_extensions import Any, Mapping
|
|
3
3
|
|
|
4
4
|
from dstack._internal.core.backends.oci.exceptions import any_oci_exception
|
|
5
|
-
from dstack._internal.core.
|
|
5
|
+
from dstack._internal.core.backends.oci.models import AnyOCICreds, OCIDefaultCreds
|
|
6
6
|
from dstack._internal.core.models.common import is_core_model_instance
|
|
7
7
|
|
|
8
8
|
|
|
@@ -20,7 +20,3 @@ def creds_valid(creds: AnyOCICreds) -> bool:
|
|
|
20
20
|
except any_oci_exception:
|
|
21
21
|
return False
|
|
22
22
|
return True
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
def default_creds_available() -> bool:
|
|
26
|
-
return creds_valid(OCIDefaultCreds())
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
from dstack._internal.core.backends.base.backend import Backend
|
|
2
|
+
from dstack._internal.core.backends.oci.compute import OCICompute
|
|
3
|
+
from dstack._internal.core.backends.oci.models import OCIConfig
|
|
4
|
+
from dstack._internal.core.models.backends.base import BackendType
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class OCIBackend(Backend):
|
|
8
|
+
TYPE = BackendType.OCI
|
|
9
|
+
COMPUTE_CLASS = OCICompute
|
|
10
|
+
|
|
11
|
+
def __init__(self, config: OCIConfig):
|
|
12
|
+
self.config = config
|
|
13
|
+
self._compute = OCICompute(self.config)
|
|
14
|
+
|
|
15
|
+
def compute(self) -> OCICompute:
|
|
16
|
+
return self._compute
|
|
@@ -6,13 +6,14 @@ import oci
|
|
|
6
6
|
|
|
7
7
|
from dstack._internal.core.backends.base.compute import (
|
|
8
8
|
Compute,
|
|
9
|
+
ComputeWithCreateInstanceSupport,
|
|
10
|
+
ComputeWithMultinodeSupport,
|
|
9
11
|
generate_unique_instance_name,
|
|
10
|
-
get_job_instance_name,
|
|
11
12
|
get_user_data,
|
|
12
13
|
)
|
|
13
14
|
from dstack._internal.core.backends.base.offers import get_catalog_offers
|
|
14
15
|
from dstack._internal.core.backends.oci import resources
|
|
15
|
-
from dstack._internal.core.backends.oci.
|
|
16
|
+
from dstack._internal.core.backends.oci.models import OCIConfig
|
|
16
17
|
from dstack._internal.core.backends.oci.region import make_region_clients_map
|
|
17
18
|
from dstack._internal.core.errors import NoCapacityError
|
|
18
19
|
from dstack._internal.core.models.backends.base import BackendType
|
|
@@ -21,11 +22,9 @@ from dstack._internal.core.models.instances import (
|
|
|
21
22
|
InstanceConfiguration,
|
|
22
23
|
InstanceOffer,
|
|
23
24
|
InstanceOfferWithAvailability,
|
|
24
|
-
SSHKey,
|
|
25
25
|
)
|
|
26
26
|
from dstack._internal.core.models.resources import Memory, Range
|
|
27
|
-
from dstack._internal.core.models.runs import
|
|
28
|
-
from dstack._internal.core.models.volumes import Volume
|
|
27
|
+
from dstack._internal.core.models.runs import JobProvisioningData, Requirements
|
|
29
28
|
|
|
30
29
|
SUPPORTED_SHAPE_FAMILIES = [
|
|
31
30
|
"VM.Standard2.",
|
|
@@ -46,7 +45,11 @@ SUPPORTED_SHAPE_FAMILIES = [
|
|
|
46
45
|
CONFIGURABLE_DISK_SIZE = Range[Memory](min=Memory.parse("50GB"), max=Memory.parse("32TB"))
|
|
47
46
|
|
|
48
47
|
|
|
49
|
-
class OCICompute(
|
|
48
|
+
class OCICompute(
|
|
49
|
+
ComputeWithCreateInstanceSupport,
|
|
50
|
+
ComputeWithMultinodeSupport,
|
|
51
|
+
Compute,
|
|
52
|
+
):
|
|
50
53
|
def __init__(self, config: OCIConfig):
|
|
51
54
|
super().__init__()
|
|
52
55
|
self.config = config
|
|
@@ -92,23 +95,6 @@ class OCICompute(Compute):
|
|
|
92
95
|
|
|
93
96
|
return offers_with_availability
|
|
94
97
|
|
|
95
|
-
def run_job(
|
|
96
|
-
self,
|
|
97
|
-
run: Run,
|
|
98
|
-
job: Job,
|
|
99
|
-
instance_offer: InstanceOfferWithAvailability,
|
|
100
|
-
project_ssh_public_key: str,
|
|
101
|
-
project_ssh_private_key: str,
|
|
102
|
-
volumes: List[Volume],
|
|
103
|
-
) -> JobProvisioningData:
|
|
104
|
-
instance_config = InstanceConfiguration(
|
|
105
|
-
project_name=run.project_name,
|
|
106
|
-
instance_name=get_job_instance_name(run, job),
|
|
107
|
-
ssh_keys=[SSHKey(public=project_ssh_public_key.strip())],
|
|
108
|
-
user=run.user,
|
|
109
|
-
)
|
|
110
|
-
return self.create_instance(instance_offer, instance_config)
|
|
111
|
-
|
|
112
98
|
def terminate_instance(
|
|
113
99
|
self, instance_id: str, region: str, backend_data: Optional[str] = None
|
|
114
100
|
) -> None:
|
dstack/_internal/{server/services/backends/configurators/oci.py → core/backends/oci/configurator.py}
RENAMED
|
@@ -1,9 +1,23 @@
|
|
|
1
1
|
import json
|
|
2
2
|
from typing import Dict, Iterable, List, Set, Tuple
|
|
3
3
|
|
|
4
|
-
from dstack._internal.core.backends.
|
|
5
|
-
|
|
4
|
+
from dstack._internal.core.backends.base.configurator import (
|
|
5
|
+
BackendRecord,
|
|
6
|
+
Configurator,
|
|
7
|
+
raise_invalid_credentials_error,
|
|
8
|
+
)
|
|
9
|
+
from dstack._internal.core.backends.oci import resources
|
|
10
|
+
from dstack._internal.core.backends.oci.backend import OCIBackend
|
|
6
11
|
from dstack._internal.core.backends.oci.exceptions import any_oci_exception
|
|
12
|
+
from dstack._internal.core.backends.oci.models import (
|
|
13
|
+
AnyOCIBackendConfig,
|
|
14
|
+
OCIBackendConfig,
|
|
15
|
+
OCIBackendConfigWithCreds,
|
|
16
|
+
OCIConfig,
|
|
17
|
+
OCICreds,
|
|
18
|
+
OCIDefaultCreds,
|
|
19
|
+
OCIStoredConfig,
|
|
20
|
+
)
|
|
7
21
|
from dstack._internal.core.backends.oci.region import (
|
|
8
22
|
get_subscribed_regions,
|
|
9
23
|
make_region_client,
|
|
@@ -12,26 +26,8 @@ from dstack._internal.core.backends.oci.region import (
|
|
|
12
26
|
from dstack._internal.core.errors import ServerClientError
|
|
13
27
|
from dstack._internal.core.models.backends.base import (
|
|
14
28
|
BackendType,
|
|
15
|
-
ConfigElementValue,
|
|
16
|
-
ConfigMultiElement,
|
|
17
|
-
)
|
|
18
|
-
from dstack._internal.core.models.backends.oci import (
|
|
19
|
-
AnyOCIConfigInfo,
|
|
20
|
-
OCIConfigInfo,
|
|
21
|
-
OCIConfigInfoWithCreds,
|
|
22
|
-
OCIConfigInfoWithCredsPartial,
|
|
23
|
-
OCIConfigValues,
|
|
24
|
-
OCICreds,
|
|
25
|
-
OCIDefaultCreds,
|
|
26
|
-
OCIStoredConfig,
|
|
27
29
|
)
|
|
28
30
|
from dstack._internal.core.models.common import is_core_model_instance
|
|
29
|
-
from dstack._internal.server import settings
|
|
30
|
-
from dstack._internal.server.models import BackendModel, DecryptedString, ProjectModel
|
|
31
|
-
from dstack._internal.server.services.backends.configurators.base import (
|
|
32
|
-
Configurator,
|
|
33
|
-
raise_invalid_credentials_error,
|
|
34
|
-
)
|
|
35
31
|
|
|
36
32
|
# where dstack images are published
|
|
37
33
|
SUPPORTED_REGIONS = frozenset(
|
|
@@ -48,56 +44,23 @@ SUPPORTED_REGIONS = frozenset(
|
|
|
48
44
|
|
|
49
45
|
|
|
50
46
|
class OCIConfigurator(Configurator):
|
|
51
|
-
TYPE
|
|
52
|
-
|
|
53
|
-
def get_default_configs(self) -> List[OCIConfigInfoWithCreds]:
|
|
54
|
-
creds = OCIDefaultCreds()
|
|
55
|
-
try:
|
|
56
|
-
subscribed_regions = get_subscribed_regions(creds).names
|
|
57
|
-
except any_oci_exception:
|
|
58
|
-
return []
|
|
59
|
-
return [
|
|
60
|
-
OCIConfigInfoWithCreds(
|
|
61
|
-
regions=list(subscribed_regions & SUPPORTED_REGIONS),
|
|
62
|
-
creds=creds,
|
|
63
|
-
)
|
|
64
|
-
]
|
|
47
|
+
TYPE = BackendType.OCI
|
|
48
|
+
BACKEND_CLASS = OCIBackend
|
|
65
49
|
|
|
66
|
-
def
|
|
67
|
-
|
|
68
|
-
config_values.default_creds = (
|
|
69
|
-
settings.DEFAULT_CREDS_ENABLED and auth.default_creds_available()
|
|
70
|
-
)
|
|
71
|
-
if config.creds is None:
|
|
72
|
-
return config_values
|
|
73
|
-
if (
|
|
74
|
-
is_core_model_instance(config.creds, OCIDefaultCreds)
|
|
75
|
-
and not settings.DEFAULT_CREDS_ENABLED
|
|
76
|
-
):
|
|
50
|
+
def validate_config(self, config: OCIBackendConfigWithCreds, default_creds_enabled: bool):
|
|
51
|
+
if is_core_model_instance(config.creds, OCIDefaultCreds) and not default_creds_enabled:
|
|
77
52
|
raise_invalid_credentials_error(
|
|
78
53
|
fields=[["creds"]],
|
|
79
54
|
details="Default credentials are forbidden by dstack settings",
|
|
80
55
|
)
|
|
81
|
-
|
|
82
56
|
try:
|
|
83
|
-
|
|
57
|
+
get_subscribed_regions(config.creds).names
|
|
84
58
|
except any_oci_exception as e:
|
|
85
59
|
raise_invalid_credentials_error(fields=[["creds"]], details=e)
|
|
86
60
|
|
|
87
|
-
if config.regions:
|
|
88
|
-
selected_regions = [r for r in config.regions if r in available_regions]
|
|
89
|
-
else:
|
|
90
|
-
selected_regions = list(available_regions)
|
|
91
|
-
|
|
92
|
-
config_values.regions = self._get_regions_element(
|
|
93
|
-
available=available_regions,
|
|
94
|
-
selected=selected_regions,
|
|
95
|
-
)
|
|
96
|
-
return config_values
|
|
97
|
-
|
|
98
61
|
def create_backend(
|
|
99
|
-
self,
|
|
100
|
-
) ->
|
|
62
|
+
self, project_name: str, config: OCIBackendConfigWithCreds
|
|
63
|
+
) -> BackendRecord:
|
|
101
64
|
try:
|
|
102
65
|
subscribed_regions = get_subscribed_regions(config.creds)
|
|
103
66
|
except any_oci_exception as e:
|
|
@@ -109,44 +72,36 @@ class OCIConfigurator(Configurator):
|
|
|
109
72
|
_raise_if_regions_unavailable(config.regions, subscribed_regions.names)
|
|
110
73
|
|
|
111
74
|
compartment_id, subnet_ids_per_region = _create_resources(
|
|
112
|
-
|
|
75
|
+
project_name, config, subscribed_regions.home_region_name
|
|
113
76
|
)
|
|
114
77
|
config.compartment_id = compartment_id
|
|
115
78
|
stored_config = OCIStoredConfig.__response__(
|
|
116
79
|
**config.dict(), subnet_ids_per_region=subnet_ids_per_region
|
|
117
80
|
)
|
|
118
81
|
|
|
119
|
-
return
|
|
120
|
-
project_id=project.id,
|
|
121
|
-
type=self.TYPE.value,
|
|
82
|
+
return BackendRecord(
|
|
122
83
|
config=stored_config.json(),
|
|
123
|
-
auth=
|
|
84
|
+
auth=OCICreds.parse_obj(config.creds).json(),
|
|
124
85
|
)
|
|
125
86
|
|
|
126
|
-
def
|
|
127
|
-
|
|
87
|
+
def get_backend_config(
|
|
88
|
+
self, record: BackendRecord, include_creds: bool
|
|
89
|
+
) -> AnyOCIBackendConfig:
|
|
90
|
+
config = self._get_config(record)
|
|
128
91
|
if include_creds:
|
|
129
|
-
return
|
|
130
|
-
return
|
|
92
|
+
return OCIBackendConfigWithCreds.__response__.parse_obj(config)
|
|
93
|
+
return OCIBackendConfig.__response__.parse_obj(config)
|
|
131
94
|
|
|
132
|
-
def get_backend(self,
|
|
133
|
-
config = self.
|
|
95
|
+
def get_backend(self, record: BackendRecord) -> OCIBackend:
|
|
96
|
+
config = self._get_config(record)
|
|
134
97
|
return OCIBackend(config=config)
|
|
135
98
|
|
|
136
|
-
def
|
|
99
|
+
def _get_config(self, record: BackendRecord) -> OCIConfig:
|
|
137
100
|
return OCIConfig.__response__(
|
|
138
|
-
**json.loads(
|
|
139
|
-
creds=OCICreds.parse_raw(
|
|
101
|
+
**json.loads(record.config),
|
|
102
|
+
creds=OCICreds.parse_raw(record.auth).__root__,
|
|
140
103
|
)
|
|
141
104
|
|
|
142
|
-
def _get_regions_element(
|
|
143
|
-
self, available: Iterable[str], selected: List[str]
|
|
144
|
-
) -> ConfigMultiElement:
|
|
145
|
-
element = ConfigMultiElement(selected=selected)
|
|
146
|
-
for region in available:
|
|
147
|
-
element.values.append(ConfigElementValue(value=region, label=region))
|
|
148
|
-
return element
|
|
149
|
-
|
|
150
105
|
|
|
151
106
|
def _filter_supported_regions(subscribed_region_names: Set[str]) -> List[str]:
|
|
152
107
|
available_regions = subscribed_region_names & SUPPORTED_REGIONS
|
|
@@ -178,13 +133,13 @@ def _raise_if_regions_unavailable(
|
|
|
178
133
|
|
|
179
134
|
|
|
180
135
|
def _create_resources(
|
|
181
|
-
|
|
136
|
+
project_name: str, config: OCIBackendConfigWithCreds, home_region: str
|
|
182
137
|
) -> Tuple[str, Dict[str, str]]:
|
|
183
138
|
compartment_id = config.compartment_id
|
|
184
139
|
if not compartment_id:
|
|
185
140
|
home_region_client = make_region_client(home_region, config.creds)
|
|
186
141
|
compartment_id = resources.get_or_create_compartment(
|
|
187
|
-
f"dstack-{
|
|
142
|
+
f"dstack-{project_name}",
|
|
188
143
|
home_region_client.client_config["tenancy"],
|
|
189
144
|
home_region_client.identity_client,
|
|
190
145
|
).id
|
|
@@ -192,7 +147,7 @@ def _create_resources(
|
|
|
192
147
|
region_clients = make_region_clients_map(config.regions, config.creds)
|
|
193
148
|
resources.wait_until_compartment_active(compartment_id, region_clients)
|
|
194
149
|
subnets_per_region = resources.set_up_network_resources(
|
|
195
|
-
compartment_id,
|
|
150
|
+
compartment_id, project_name, region_clients
|
|
196
151
|
)
|
|
197
152
|
|
|
198
153
|
return compartment_id, subnets_per_region
|