dstack 0.18.44__py3-none-any.whl → 0.19.0__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.
Potentially problematic release.
This version of dstack might be problematic. Click here for more details.
- 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-4a0fe83e84574654e397.js} +18 -14
- dstack/_internal/server/statics/{main-4eb116b97819badd1e2c.js.map → main-4a0fe83e84574654e397.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.0.dist-info}/METADATA +1 -1
- {dstack-0.18.44.dist-info → dstack-0.19.0.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.0.dist-info}/LICENSE.md +0 -0
- {dstack-0.18.44.dist-info → dstack-0.19.0.dist-info}/WHEEL +0 -0
- {dstack-0.18.44.dist-info → dstack-0.19.0.dist-info}/entry_points.txt +0 -0
- {dstack-0.18.44.dist-info → dstack-0.19.0.dist-info}/top_level.txt +0 -0
|
@@ -1,187 +1,61 @@
|
|
|
1
1
|
import asyncio
|
|
2
2
|
import heapq
|
|
3
|
-
from typing import Callable, Coroutine, Dict, List, Optional, Tuple
|
|
3
|
+
from typing import Callable, Coroutine, Dict, List, Optional, Tuple
|
|
4
4
|
from uuid import UUID
|
|
5
5
|
|
|
6
6
|
from sqlalchemy import delete, update
|
|
7
7
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
8
8
|
|
|
9
|
-
from dstack._internal.core.backends.base import Backend
|
|
10
|
-
from dstack._internal.core.backends.
|
|
9
|
+
from dstack._internal.core.backends.base.backend import Backend
|
|
10
|
+
from dstack._internal.core.backends.base.configurator import (
|
|
11
|
+
Configurator,
|
|
12
|
+
StoredBackendRecord,
|
|
13
|
+
)
|
|
14
|
+
from dstack._internal.core.backends.configurators import (
|
|
15
|
+
get_configurator,
|
|
16
|
+
list_available_backend_types,
|
|
17
|
+
)
|
|
18
|
+
from dstack._internal.core.backends.local.backend import LocalBackend
|
|
19
|
+
from dstack._internal.core.backends.models import (
|
|
20
|
+
AnyBackendConfig,
|
|
21
|
+
AnyBackendConfigWithCreds,
|
|
22
|
+
)
|
|
11
23
|
from dstack._internal.core.errors import (
|
|
12
24
|
BackendError,
|
|
13
25
|
BackendInvalidCredentialsError,
|
|
14
26
|
BackendNotAvailable,
|
|
15
27
|
ResourceExistsError,
|
|
28
|
+
ResourceNotExistsError,
|
|
16
29
|
ServerClientError,
|
|
17
30
|
)
|
|
18
|
-
from dstack._internal.core.models.backends import (
|
|
19
|
-
AnyConfigInfoWithCreds,
|
|
20
|
-
AnyConfigInfoWithCredsPartial,
|
|
21
|
-
AnyConfigValues,
|
|
22
|
-
)
|
|
23
31
|
from dstack._internal.core.models.backends.base import BackendType
|
|
24
32
|
from dstack._internal.core.models.instances import (
|
|
25
33
|
InstanceOfferWithAvailability,
|
|
26
34
|
)
|
|
27
35
|
from dstack._internal.core.models.runs import Requirements
|
|
28
|
-
from dstack._internal.server
|
|
29
|
-
from dstack._internal.server.
|
|
36
|
+
from dstack._internal.server import settings
|
|
37
|
+
from dstack._internal.server.models import BackendModel, DecryptedString, ProjectModel
|
|
30
38
|
from dstack._internal.server.settings import LOCAL_BACKEND_ENABLED
|
|
31
39
|
from dstack._internal.utils.common import run_async
|
|
32
40
|
from dstack._internal.utils.logging import get_logger
|
|
33
41
|
|
|
34
42
|
logger = get_logger(__name__)
|
|
35
43
|
|
|
36
|
-
_CONFIGURATOR_CLASSES: List[Type[Configurator]] = []
|
|
37
|
-
|
|
38
|
-
try:
|
|
39
|
-
from dstack._internal.server.services.backends.configurators.aws import AWSConfigurator
|
|
40
|
-
|
|
41
|
-
_CONFIGURATOR_CLASSES.append(AWSConfigurator)
|
|
42
|
-
except ImportError:
|
|
43
|
-
pass
|
|
44
|
-
|
|
45
|
-
try:
|
|
46
|
-
from dstack._internal.server.services.backends.configurators.azure import AzureConfigurator
|
|
47
|
-
|
|
48
|
-
_CONFIGURATOR_CLASSES.append(AzureConfigurator)
|
|
49
|
-
except ImportError:
|
|
50
|
-
pass
|
|
51
|
-
|
|
52
|
-
try:
|
|
53
|
-
from dstack._internal.server.services.backends.configurators.cudo import (
|
|
54
|
-
CudoConfigurator,
|
|
55
|
-
)
|
|
56
|
-
|
|
57
|
-
_CONFIGURATOR_CLASSES.append(CudoConfigurator)
|
|
58
|
-
except ImportError:
|
|
59
|
-
pass
|
|
60
|
-
|
|
61
|
-
try:
|
|
62
|
-
from dstack._internal.server.services.backends.configurators.datacrunch import (
|
|
63
|
-
DataCrunchConfigurator,
|
|
64
|
-
)
|
|
65
|
-
|
|
66
|
-
_CONFIGURATOR_CLASSES.append(DataCrunchConfigurator)
|
|
67
|
-
except ImportError:
|
|
68
|
-
pass
|
|
69
|
-
|
|
70
|
-
try:
|
|
71
|
-
from dstack._internal.server.services.backends.configurators.gcp import GCPConfigurator
|
|
72
|
-
|
|
73
|
-
_CONFIGURATOR_CLASSES.append(GCPConfigurator)
|
|
74
|
-
except ImportError:
|
|
75
|
-
pass
|
|
76
|
-
|
|
77
|
-
try:
|
|
78
|
-
from dstack._internal.server.services.backends.configurators.kubernetes import (
|
|
79
|
-
KubernetesConfigurator,
|
|
80
|
-
)
|
|
81
|
-
|
|
82
|
-
_CONFIGURATOR_CLASSES.append(KubernetesConfigurator)
|
|
83
|
-
except ImportError:
|
|
84
|
-
pass
|
|
85
|
-
|
|
86
|
-
try:
|
|
87
|
-
from dstack._internal.server.services.backends.configurators.lambdalabs import (
|
|
88
|
-
LambdaConfigurator,
|
|
89
|
-
)
|
|
90
|
-
|
|
91
|
-
_CONFIGURATOR_CLASSES.append(LambdaConfigurator)
|
|
92
|
-
except ImportError:
|
|
93
|
-
pass
|
|
94
|
-
|
|
95
|
-
try:
|
|
96
|
-
from dstack._internal.server.services.backends.configurators.nebius import NebiusConfigurator
|
|
97
|
-
|
|
98
|
-
_CONFIGURATOR_CLASSES.append(NebiusConfigurator)
|
|
99
|
-
except ImportError:
|
|
100
|
-
pass
|
|
101
|
-
|
|
102
|
-
try:
|
|
103
|
-
from dstack._internal.server.services.backends.configurators.oci import OCIConfigurator
|
|
104
|
-
|
|
105
|
-
_CONFIGURATOR_CLASSES.append(OCIConfigurator)
|
|
106
|
-
except ImportError:
|
|
107
|
-
pass
|
|
108
|
-
|
|
109
|
-
try:
|
|
110
|
-
from dstack._internal.server.services.backends.configurators.runpod import RunpodConfigurator
|
|
111
|
-
|
|
112
|
-
_CONFIGURATOR_CLASSES.append(RunpodConfigurator)
|
|
113
|
-
except ImportError:
|
|
114
|
-
pass
|
|
115
|
-
|
|
116
|
-
try:
|
|
117
|
-
from dstack._internal.server.services.backends.configurators.tensordock import (
|
|
118
|
-
TensorDockConfigurator,
|
|
119
|
-
)
|
|
120
|
-
|
|
121
|
-
_CONFIGURATOR_CLASSES.append(TensorDockConfigurator)
|
|
122
|
-
except ImportError:
|
|
123
|
-
pass
|
|
124
|
-
|
|
125
|
-
try:
|
|
126
|
-
from dstack._internal.server.services.backends.configurators.vastai import VastAIConfigurator
|
|
127
|
-
|
|
128
|
-
_CONFIGURATOR_CLASSES.append(VastAIConfigurator)
|
|
129
|
-
except ImportError:
|
|
130
|
-
pass
|
|
131
|
-
|
|
132
|
-
try:
|
|
133
|
-
from dstack._internal.server.services.backends.configurators.vultr import VultrConfigurator
|
|
134
|
-
|
|
135
|
-
_CONFIGURATOR_CLASSES.append(VultrConfigurator)
|
|
136
|
-
except ImportError:
|
|
137
|
-
pass
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
_BACKEND_TYPE_TO_CONFIGURATOR_CLASS_MAP = {c.TYPE: c for c in _CONFIGURATOR_CLASSES}
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
def register_configurator(configurator: Type[Configurator]):
|
|
144
|
-
_BACKEND_TYPE_TO_CONFIGURATOR_CLASS_MAP[configurator.TYPE] = configurator
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
def get_configurator(backend_type: Union[BackendType, str]) -> Optional[Configurator]:
|
|
148
|
-
backend_type = BackendType(backend_type)
|
|
149
|
-
configurator_class = _BACKEND_TYPE_TO_CONFIGURATOR_CLASS_MAP.get(backend_type)
|
|
150
|
-
if configurator_class is None:
|
|
151
|
-
return None
|
|
152
|
-
return configurator_class()
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
def list_available_backend_types() -> List[BackendType]:
|
|
156
|
-
available_backend_types = []
|
|
157
|
-
for configurator_class in _BACKEND_TYPE_TO_CONFIGURATOR_CLASS_MAP.values():
|
|
158
|
-
available_backend_types.append(configurator_class.TYPE)
|
|
159
|
-
return available_backend_types
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
async def get_backend_config_values(
|
|
163
|
-
config: AnyConfigInfoWithCredsPartial,
|
|
164
|
-
) -> AnyConfigValues:
|
|
165
|
-
configurator = get_configurator(config.type)
|
|
166
|
-
if configurator is None:
|
|
167
|
-
raise BackendNotAvailable()
|
|
168
|
-
config_values = await run_async(configurator.get_config_values, config)
|
|
169
|
-
return config_values
|
|
170
|
-
|
|
171
44
|
|
|
172
45
|
async def create_backend(
|
|
173
46
|
session: AsyncSession,
|
|
174
47
|
project: ProjectModel,
|
|
175
|
-
config:
|
|
176
|
-
) ->
|
|
48
|
+
config: AnyBackendConfigWithCreds,
|
|
49
|
+
) -> AnyBackendConfigWithCreds:
|
|
177
50
|
configurator = get_configurator(config.type)
|
|
178
51
|
if configurator is None:
|
|
179
52
|
raise BackendNotAvailable()
|
|
180
53
|
backend = await get_project_backend_by_type(project=project, backend_type=configurator.TYPE)
|
|
181
54
|
if backend is not None:
|
|
182
55
|
raise ResourceExistsError()
|
|
183
|
-
await
|
|
184
|
-
|
|
56
|
+
backend = await validate_and_create_backend_model(
|
|
57
|
+
project=project, configurator=configurator, config=config
|
|
58
|
+
)
|
|
185
59
|
session.add(backend)
|
|
186
60
|
await session.commit()
|
|
187
61
|
return config
|
|
@@ -190,16 +64,17 @@ async def create_backend(
|
|
|
190
64
|
async def update_backend(
|
|
191
65
|
session: AsyncSession,
|
|
192
66
|
project: ProjectModel,
|
|
193
|
-
config:
|
|
194
|
-
) ->
|
|
67
|
+
config: AnyBackendConfigWithCreds,
|
|
68
|
+
) -> AnyBackendConfigWithCreds:
|
|
195
69
|
configurator = get_configurator(config.type)
|
|
196
70
|
if configurator is None:
|
|
197
71
|
raise BackendNotAvailable()
|
|
198
72
|
backend_exists = any(configurator.TYPE == b.type for b in project.backends)
|
|
199
73
|
if not backend_exists:
|
|
200
|
-
raise
|
|
201
|
-
await
|
|
202
|
-
|
|
74
|
+
raise ResourceNotExistsError()
|
|
75
|
+
backend = await validate_and_create_backend_model(
|
|
76
|
+
project=project, configurator=configurator, config=config
|
|
77
|
+
)
|
|
203
78
|
# FIXME: potentially long write transaction
|
|
204
79
|
await session.execute(
|
|
205
80
|
update(BackendModel)
|
|
@@ -215,10 +90,31 @@ async def update_backend(
|
|
|
215
90
|
return config
|
|
216
91
|
|
|
217
92
|
|
|
218
|
-
async def
|
|
93
|
+
async def validate_and_create_backend_model(
|
|
94
|
+
project: ProjectModel,
|
|
95
|
+
configurator: Configurator,
|
|
96
|
+
config: AnyBackendConfigWithCreds,
|
|
97
|
+
) -> BackendModel:
|
|
98
|
+
await run_async(
|
|
99
|
+
configurator.validate_config, config, default_creds_enabled=settings.DEFAULT_CREDS_ENABLED
|
|
100
|
+
)
|
|
101
|
+
backend_record = await run_async(
|
|
102
|
+
configurator.create_backend,
|
|
103
|
+
project_name=project.name,
|
|
104
|
+
config=config,
|
|
105
|
+
)
|
|
106
|
+
return BackendModel(
|
|
107
|
+
project_id=project.id,
|
|
108
|
+
type=configurator.TYPE,
|
|
109
|
+
config=backend_record.config,
|
|
110
|
+
auth=DecryptedString(plaintext=backend_record.auth),
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
async def get_backend_config(
|
|
219
115
|
project: ProjectModel,
|
|
220
116
|
backend_type: BackendType,
|
|
221
|
-
) -> Optional[
|
|
117
|
+
) -> Optional[AnyBackendConfigWithCreds]:
|
|
222
118
|
configurator = get_configurator(backend_type)
|
|
223
119
|
if configurator is None:
|
|
224
120
|
raise BackendNotAvailable()
|
|
@@ -230,10 +126,31 @@ async def get_config_info(
|
|
|
230
126
|
)
|
|
231
127
|
continue
|
|
232
128
|
if backend_model.type == backend_type:
|
|
233
|
-
return
|
|
129
|
+
return get_backend_config_from_backend_model(
|
|
130
|
+
configurator, backend_model, include_creds=True
|
|
131
|
+
)
|
|
234
132
|
return None
|
|
235
133
|
|
|
236
134
|
|
|
135
|
+
def get_backend_config_from_backend_model(
|
|
136
|
+
configurator: Configurator,
|
|
137
|
+
backend_model: BackendModel,
|
|
138
|
+
include_creds: bool,
|
|
139
|
+
) -> AnyBackendConfig:
|
|
140
|
+
backend_record = get_stored_backend_record(backend_model)
|
|
141
|
+
backend_config = configurator.get_backend_config(backend_record, include_creds=include_creds)
|
|
142
|
+
return backend_config
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
def get_stored_backend_record(backend_model: BackendModel) -> StoredBackendRecord:
|
|
146
|
+
return StoredBackendRecord(
|
|
147
|
+
config=backend_model.config,
|
|
148
|
+
auth=backend_model.auth.get_plaintext_or_error(),
|
|
149
|
+
project_id=backend_model.project_id,
|
|
150
|
+
backend_id=backend_model.id,
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
|
|
237
154
|
async def delete_backends(
|
|
238
155
|
session: AsyncSession,
|
|
239
156
|
project: ProjectModel,
|
|
@@ -299,7 +216,8 @@ async def get_project_backends_with_models(project: ProjectModel) -> List[Backen
|
|
|
299
216
|
)
|
|
300
217
|
continue
|
|
301
218
|
try:
|
|
302
|
-
|
|
219
|
+
backend_record = get_stored_backend_record(backend_model)
|
|
220
|
+
backend = await run_async(configurator.get_backend, backend_record)
|
|
303
221
|
except BackendInvalidCredentialsError:
|
|
304
222
|
logger.warning(
|
|
305
223
|
"Credentials for %s backend are invalid. Backend will be ignored.",
|
|
@@ -449,3 +367,12 @@ async def get_instance_offers(
|
|
|
449
367
|
offers = heapq.merge(*offers_by_backend, key=lambda i: i[1].price)
|
|
450
368
|
# Put NOT_AVAILABLE, NO_QUOTA, and BUSY instances at the end, do not sort by price
|
|
451
369
|
return sorted(offers, key=lambda i: not i[1].availability.is_available())
|
|
370
|
+
|
|
371
|
+
|
|
372
|
+
def check_backend_type_available(backend_type: BackendType):
|
|
373
|
+
if backend_type not in list_available_backend_types():
|
|
374
|
+
raise BackendNotAvailable(
|
|
375
|
+
f"Backend {backend_type.value} not available."
|
|
376
|
+
" Ensure that backend dependencies are installed."
|
|
377
|
+
f" Available backends: {[b.value for b in list_available_backend_types()]}."
|
|
378
|
+
)
|