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
|
@@ -9,7 +9,7 @@ from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
9
9
|
from sqlalchemy.orm import joinedload, selectinload
|
|
10
10
|
|
|
11
11
|
from dstack._internal.core.backends import BACKENDS_WITH_CREATE_INSTANCE_SUPPORT
|
|
12
|
-
from dstack._internal.core.backends.base import Backend
|
|
12
|
+
from dstack._internal.core.backends.base.backend import Backend
|
|
13
13
|
from dstack._internal.core.errors import (
|
|
14
14
|
ForbiddenError,
|
|
15
15
|
ResourceExistsError,
|
|
@@ -27,16 +27,13 @@ from dstack._internal.core.models.fleets import (
|
|
|
27
27
|
SSHParams,
|
|
28
28
|
)
|
|
29
29
|
from dstack._internal.core.models.instances import (
|
|
30
|
-
InstanceConfiguration,
|
|
31
30
|
InstanceOfferWithAvailability,
|
|
32
31
|
InstanceStatus,
|
|
33
32
|
RemoteConnectionInfo,
|
|
34
33
|
SSHConnectionParams,
|
|
35
34
|
SSHKey,
|
|
36
35
|
)
|
|
37
|
-
from dstack._internal.core.models.pools import Instance
|
|
38
36
|
from dstack._internal.core.models.profiles import (
|
|
39
|
-
DEFAULT_POOL_TERMINATION_IDLE_TIME,
|
|
40
37
|
Profile,
|
|
41
38
|
SpotPolicy,
|
|
42
39
|
)
|
|
@@ -44,29 +41,26 @@ from dstack._internal.core.models.resources import ResourcesSpec
|
|
|
44
41
|
from dstack._internal.core.models.runs import Requirements, get_policy_map
|
|
45
42
|
from dstack._internal.core.models.users import GlobalRole
|
|
46
43
|
from dstack._internal.core.services import validate_dstack_resource_name
|
|
47
|
-
from dstack._internal.core.services.profiles import get_termination
|
|
48
44
|
from dstack._internal.server.db import get_db
|
|
49
45
|
from dstack._internal.server.models import (
|
|
50
46
|
FleetModel,
|
|
51
47
|
InstanceModel,
|
|
52
|
-
PoolModel,
|
|
53
48
|
ProjectModel,
|
|
54
49
|
UserModel,
|
|
55
50
|
)
|
|
51
|
+
from dstack._internal.server.services import instances as instances_services
|
|
56
52
|
from dstack._internal.server.services import offers as offers_services
|
|
57
|
-
from dstack._internal.server.services import
|
|
53
|
+
from dstack._internal.server.services.instances import list_active_remote_instances
|
|
58
54
|
from dstack._internal.server.services.locking import (
|
|
59
55
|
get_locker,
|
|
60
56
|
string_to_lock_id,
|
|
61
57
|
)
|
|
62
|
-
from dstack._internal.server.services.pools import list_active_remote_instances
|
|
63
58
|
from dstack._internal.server.services.projects import (
|
|
64
59
|
get_member,
|
|
65
60
|
get_member_permissions,
|
|
66
61
|
list_project_models,
|
|
67
62
|
list_user_project_models,
|
|
68
63
|
)
|
|
69
|
-
from dstack._internal.utils import common as common_utils
|
|
70
64
|
from dstack._internal.utils import random_names
|
|
71
65
|
from dstack._internal.utils.logging import get_logger
|
|
72
66
|
from dstack._internal.utils.ssh import pkey_from_str
|
|
@@ -291,7 +285,7 @@ async def get_create_instance_offers(
|
|
|
291
285
|
fleet = fleet_model_to_fleet(fleet_model)
|
|
292
286
|
multinode = fleet.spec.configuration.placement == InstanceGroupPlacement.CLUSTER
|
|
293
287
|
for instance in fleet_model.instances:
|
|
294
|
-
jpd =
|
|
288
|
+
jpd = instances_services.get_instance_provisioning_data(instance)
|
|
295
289
|
if jpd is not None:
|
|
296
290
|
master_job_provisioning_data = jpd
|
|
297
291
|
break
|
|
@@ -308,7 +302,7 @@ async def get_create_instance_offers(
|
|
|
308
302
|
offers = [
|
|
309
303
|
(backend, offer)
|
|
310
304
|
for backend, offer in offers
|
|
311
|
-
if backend
|
|
305
|
+
if offer.backend in BACKENDS_WITH_CREATE_INSTANCE_SUPPORT
|
|
312
306
|
]
|
|
313
307
|
return offers
|
|
314
308
|
|
|
@@ -346,9 +340,6 @@ async def create_fleet(
|
|
|
346
340
|
else:
|
|
347
341
|
spec.configuration.name = await generate_fleet_name(session=session, project=project)
|
|
348
342
|
|
|
349
|
-
pool = await pools_services.get_or_create_pool_by_name(
|
|
350
|
-
session=session, project=project, pool_name=None
|
|
351
|
-
)
|
|
352
343
|
fleet_model = FleetModel(
|
|
353
344
|
id=uuid.uuid4(),
|
|
354
345
|
name=spec.configuration.name,
|
|
@@ -362,7 +353,6 @@ async def create_fleet(
|
|
|
362
353
|
for i, host in enumerate(spec.configuration.ssh_config.hosts):
|
|
363
354
|
instances_model = await create_fleet_ssh_instance_model(
|
|
364
355
|
project=project,
|
|
365
|
-
pool=pool,
|
|
366
356
|
spec=spec,
|
|
367
357
|
ssh_params=spec.configuration.ssh_config,
|
|
368
358
|
env=spec.configuration.env,
|
|
@@ -380,7 +370,6 @@ async def create_fleet(
|
|
|
380
370
|
session=session,
|
|
381
371
|
project=project,
|
|
382
372
|
user=user,
|
|
383
|
-
pool=pool,
|
|
384
373
|
spec=spec,
|
|
385
374
|
placement_group_name=placement_group_name,
|
|
386
375
|
reservation=spec.configuration.reservation,
|
|
@@ -395,7 +384,6 @@ async def create_fleet_instance_model(
|
|
|
395
384
|
session: AsyncSession,
|
|
396
385
|
project: ProjectModel,
|
|
397
386
|
user: UserModel,
|
|
398
|
-
pool: PoolModel,
|
|
399
387
|
spec: FleetSpec,
|
|
400
388
|
placement_group_name: Optional[str],
|
|
401
389
|
reservation: Optional[str],
|
|
@@ -403,11 +391,10 @@ async def create_fleet_instance_model(
|
|
|
403
391
|
) -> InstanceModel:
|
|
404
392
|
profile = spec.merged_profile
|
|
405
393
|
requirements = _get_fleet_requirements(spec)
|
|
406
|
-
instance_model = await
|
|
394
|
+
instance_model = await instances_services.create_instance_model(
|
|
407
395
|
session=session,
|
|
408
396
|
project=project,
|
|
409
397
|
user=user,
|
|
410
|
-
pool=pool,
|
|
411
398
|
profile=profile,
|
|
412
399
|
requirements=requirements,
|
|
413
400
|
instance_name=f"{spec.configuration.name}-{instance_num}",
|
|
@@ -421,7 +408,6 @@ async def create_fleet_instance_model(
|
|
|
421
408
|
|
|
422
409
|
async def create_fleet_ssh_instance_model(
|
|
423
410
|
project: ProjectModel,
|
|
424
|
-
pool: PoolModel,
|
|
425
411
|
spec: FleetSpec,
|
|
426
412
|
ssh_params: SSHParams,
|
|
427
413
|
env: Env,
|
|
@@ -460,9 +446,8 @@ async def create_fleet_ssh_instance_model(
|
|
|
460
446
|
ssh_proxy = None
|
|
461
447
|
ssh_proxy_keys = None
|
|
462
448
|
|
|
463
|
-
instance_model = await
|
|
449
|
+
instance_model = await instances_services.create_ssh_instance_model(
|
|
464
450
|
project=project,
|
|
465
|
-
pool=pool,
|
|
466
451
|
instance_name=f"{spec.configuration.name}-{instance_num}",
|
|
467
452
|
instance_num=instance_num,
|
|
468
453
|
region="remote",
|
|
@@ -541,7 +526,7 @@ def fleet_model_to_fleet(
|
|
|
541
526
|
instance_models = fleet_model.instances
|
|
542
527
|
if not include_deleted_instances:
|
|
543
528
|
instance_models = [i for i in instance_models if not i.deleted]
|
|
544
|
-
instances = [
|
|
529
|
+
instances = [instances_services.instance_model_to_instance(i) for i in instance_models]
|
|
545
530
|
instances = sorted(instances, key=lambda i: i.instance_num)
|
|
546
531
|
spec = get_fleet_spec(fleet_model)
|
|
547
532
|
if not include_sensitive:
|
|
@@ -585,86 +570,6 @@ def is_fleet_empty(fleet_model: FleetModel) -> bool:
|
|
|
585
570
|
return len(active_instances) == 0
|
|
586
571
|
|
|
587
572
|
|
|
588
|
-
async def create_instance(
|
|
589
|
-
session: AsyncSession,
|
|
590
|
-
project: ProjectModel,
|
|
591
|
-
user: UserModel,
|
|
592
|
-
profile: Profile,
|
|
593
|
-
requirements: Requirements,
|
|
594
|
-
) -> Instance:
|
|
595
|
-
offers = await get_create_instance_offers(
|
|
596
|
-
project=project,
|
|
597
|
-
profile=profile,
|
|
598
|
-
requirements=requirements,
|
|
599
|
-
exclude_not_available=True,
|
|
600
|
-
)
|
|
601
|
-
|
|
602
|
-
# Raise error if no backends suppport create_instance
|
|
603
|
-
backend_types = set((backend.TYPE for backend, _ in offers))
|
|
604
|
-
if all(
|
|
605
|
-
(backend_type not in BACKENDS_WITH_CREATE_INSTANCE_SUPPORT)
|
|
606
|
-
for backend_type in backend_types
|
|
607
|
-
):
|
|
608
|
-
backends = ", ".join(sorted(backend_types))
|
|
609
|
-
raise ServerClientError(
|
|
610
|
-
f"Backends {backends} do not support create_instance. Try to select other backends."
|
|
611
|
-
)
|
|
612
|
-
|
|
613
|
-
pool = await pools_services.get_or_create_pool_by_name(session, project, profile.pool_name)
|
|
614
|
-
instance_name = await pools_services.generate_instance_name(
|
|
615
|
-
session=session,
|
|
616
|
-
project=project,
|
|
617
|
-
pool_name=pool.name,
|
|
618
|
-
)
|
|
619
|
-
|
|
620
|
-
termination_policy, termination_idle_time = get_termination(
|
|
621
|
-
profile, DEFAULT_POOL_TERMINATION_IDLE_TIME
|
|
622
|
-
)
|
|
623
|
-
instance = InstanceModel(
|
|
624
|
-
id=uuid.uuid4(),
|
|
625
|
-
name=instance_name,
|
|
626
|
-
instance_num=0,
|
|
627
|
-
project=project,
|
|
628
|
-
pool=pool,
|
|
629
|
-
created_at=common_utils.get_current_datetime(),
|
|
630
|
-
status=InstanceStatus.PENDING,
|
|
631
|
-
unreachable=False,
|
|
632
|
-
profile=profile.json(),
|
|
633
|
-
requirements=requirements.json(),
|
|
634
|
-
instance_configuration=None,
|
|
635
|
-
termination_policy=termination_policy,
|
|
636
|
-
termination_idle_time=termination_idle_time,
|
|
637
|
-
total_blocks=1,
|
|
638
|
-
busy_blocks=0,
|
|
639
|
-
)
|
|
640
|
-
logger.info(
|
|
641
|
-
"Added a new instance %s",
|
|
642
|
-
instance.name,
|
|
643
|
-
extra={
|
|
644
|
-
"instance_name": instance.name,
|
|
645
|
-
"instance_status": InstanceStatus.PENDING.value,
|
|
646
|
-
},
|
|
647
|
-
)
|
|
648
|
-
session.add(instance)
|
|
649
|
-
await session.commit()
|
|
650
|
-
|
|
651
|
-
project_ssh_key = SSHKey(
|
|
652
|
-
public=project.ssh_public_key.strip(),
|
|
653
|
-
private=project.ssh_private_key.strip(),
|
|
654
|
-
)
|
|
655
|
-
instance_config = InstanceConfiguration(
|
|
656
|
-
project_name=project.name,
|
|
657
|
-
instance_name=instance_name,
|
|
658
|
-
instance_id=str(instance.id),
|
|
659
|
-
ssh_keys=[project_ssh_key],
|
|
660
|
-
user=user.name,
|
|
661
|
-
)
|
|
662
|
-
instance.instance_configuration = instance_config.json()
|
|
663
|
-
await session.commit()
|
|
664
|
-
|
|
665
|
-
return pools_services.instance_model_to_instance(instance)
|
|
666
|
-
|
|
667
|
-
|
|
668
573
|
def _check_can_manage_ssh_fleets(user: UserModel, project: ProjectModel):
|
|
669
574
|
if user.global_role == GlobalRole.ADMIN:
|
|
670
575
|
return
|
|
@@ -16,6 +16,7 @@ from dstack._internal.core.backends import (
|
|
|
16
16
|
)
|
|
17
17
|
from dstack._internal.core.backends.base.compute import (
|
|
18
18
|
Compute,
|
|
19
|
+
ComputeWithGatewaySupport,
|
|
19
20
|
get_dstack_gateway_wheel,
|
|
20
21
|
get_dstack_runner_version,
|
|
21
22
|
)
|
|
@@ -38,6 +39,7 @@ from dstack._internal.server import settings
|
|
|
38
39
|
from dstack._internal.server.db import get_db
|
|
39
40
|
from dstack._internal.server.models import GatewayComputeModel, GatewayModel, ProjectModel
|
|
40
41
|
from dstack._internal.server.services.backends import (
|
|
42
|
+
check_backend_type_available,
|
|
41
43
|
get_project_backend_by_type_or_error,
|
|
42
44
|
get_project_backend_with_model_by_type_or_error,
|
|
43
45
|
)
|
|
@@ -91,6 +93,7 @@ async def create_gateway_compute(
|
|
|
91
93
|
configuration: GatewayConfiguration,
|
|
92
94
|
backend_id: Optional[uuid.UUID] = None,
|
|
93
95
|
) -> GatewayComputeModel:
|
|
96
|
+
assert isinstance(backend_compute, ComputeWithGatewaySupport)
|
|
94
97
|
private_bytes, public_bytes = generate_rsa_key_pair_bytes()
|
|
95
98
|
gateway_ssh_private_key = private_bytes.decode()
|
|
96
99
|
gateway_ssh_public_key = public_bytes.decode()
|
|
@@ -228,6 +231,8 @@ async def delete_gateways(
|
|
|
228
231
|
backend = await get_project_backend_by_type_or_error(
|
|
229
232
|
project=project, backend_type=gateway_model.backend.type
|
|
230
233
|
)
|
|
234
|
+
compute = backend.compute()
|
|
235
|
+
assert isinstance(compute, ComputeWithGatewaySupport)
|
|
231
236
|
gateway_compute_configuration = get_gateway_compute_configuration(gateway_model)
|
|
232
237
|
if (
|
|
233
238
|
gateway_model.gateway_compute is not None
|
|
@@ -236,7 +241,7 @@ async def delete_gateways(
|
|
|
236
241
|
logger.info("Deleting gateway compute for %s...", gateway_model.name)
|
|
237
242
|
try:
|
|
238
243
|
await run_async(
|
|
239
|
-
|
|
244
|
+
compute.terminate_gateway,
|
|
240
245
|
gateway_model.gateway_compute.instance_id,
|
|
241
246
|
gateway_compute_configuration,
|
|
242
247
|
gateway_model.gateway_compute.backend_data,
|
|
@@ -533,10 +538,12 @@ def gateway_model_to_gateway(gateway_model: GatewayModel) -> Gateway:
|
|
|
533
538
|
|
|
534
539
|
|
|
535
540
|
def _validate_gateway_configuration(configuration: GatewayConfiguration):
|
|
541
|
+
check_backend_type_available(configuration.backend)
|
|
536
542
|
if configuration.backend not in BACKENDS_WITH_GATEWAY_SUPPORT:
|
|
537
543
|
raise ServerClientError(
|
|
538
|
-
f"Gateways are not supported for {configuration.backend.value} backend.
|
|
539
|
-
|
|
544
|
+
f"Gateways are not supported for {configuration.backend.value} backend."
|
|
545
|
+
" Available backends with gateway support:"
|
|
546
|
+
f" {[b.value for b in BACKENDS_WITH_GATEWAY_SUPPORT]}."
|
|
540
547
|
)
|
|
541
548
|
|
|
542
549
|
if configuration.name is not None:
|
|
@@ -548,7 +555,8 @@ def _validate_gateway_configuration(configuration: GatewayConfiguration):
|
|
|
548
555
|
):
|
|
549
556
|
raise ServerClientError(
|
|
550
557
|
f"Private gateways are not supported for {configuration.backend.value} backend. "
|
|
551
|
-
|
|
558
|
+
" Available backends with private gateway support:"
|
|
559
|
+
f" {[b.value for b in BACKENDS_WITH_PRIVATE_GATEWAY_SUPPORT]}."
|
|
552
560
|
)
|
|
553
561
|
|
|
554
562
|
if configuration.certificate is not None:
|