dstack 0.18.41__py3-none-any.whl → 0.18.42__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/utils/volume.py +9 -0
- dstack/_internal/core/backends/aws/compute.py +2 -1
- dstack/_internal/core/backends/gcp/compute.py +2 -1
- dstack/_internal/core/models/runs.py +3 -3
- dstack/_internal/core/models/volumes.py +23 -0
- dstack/_internal/server/background/tasks/process_instances.py +2 -3
- dstack/_internal/server/background/tasks/process_running_jobs.py +4 -0
- dstack/_internal/server/background/tasks/process_submitted_jobs.py +12 -7
- dstack/_internal/server/background/tasks/process_terminating_jobs.py +13 -2
- dstack/_internal/server/background/tasks/process_volumes.py +11 -1
- dstack/_internal/server/migrations/versions/a751ef183f27_move_attachment_data_to_volumes_.py +34 -0
- dstack/_internal/server/models.py +17 -19
- dstack/_internal/server/services/fleets.py +5 -1
- dstack/_internal/server/services/jobs/__init__.py +4 -4
- dstack/_internal/server/services/offers.py +7 -7
- dstack/_internal/server/services/pools.py +3 -3
- dstack/_internal/server/services/runner/client.py +8 -5
- dstack/_internal/server/services/volumes.py +68 -9
- dstack/_internal/server/testing/common.py +13 -9
- dstack/version.py +1 -1
- {dstack-0.18.41.dist-info → dstack-0.18.42.dist-info}/METADATA +1 -1
- {dstack-0.18.41.dist-info → dstack-0.18.42.dist-info}/RECORD +33 -31
- tests/_internal/server/background/tasks/test_process_running_jobs.py +1 -0
- tests/_internal/server/background/tasks/test_process_submitted_jobs.py +5 -3
- tests/_internal/server/background/tasks/test_process_terminating_jobs.py +11 -6
- tests/_internal/server/routers/test_volumes.py +9 -2
- tests/_internal/server/services/runner/test_client.py +22 -3
- tests/_internal/server/services/test_offers.py +167 -0
- tests/_internal/server/services/test_pools.py +105 -1
- {dstack-0.18.41.dist-info → dstack-0.18.42.dist-info}/LICENSE.md +0 -0
- {dstack-0.18.41.dist-info → dstack-0.18.42.dist-info}/WHEEL +0 -0
- {dstack-0.18.41.dist-info → dstack-0.18.42.dist-info}/entry_points.txt +0 -0
- {dstack-0.18.41.dist-info → dstack-0.18.42.dist-info}/top_level.txt +0 -0
|
@@ -15,19 +15,28 @@ from dstack._internal.core.errors import (
|
|
|
15
15
|
from dstack._internal.core.models.users import GlobalRole
|
|
16
16
|
from dstack._internal.core.models.volumes import (
|
|
17
17
|
Volume,
|
|
18
|
+
VolumeAttachment,
|
|
18
19
|
VolumeAttachmentData,
|
|
19
20
|
VolumeConfiguration,
|
|
21
|
+
VolumeInstance,
|
|
20
22
|
VolumeProvisioningData,
|
|
21
23
|
VolumeStatus,
|
|
22
24
|
)
|
|
23
25
|
from dstack._internal.core.services import validate_dstack_resource_name
|
|
24
26
|
from dstack._internal.server.db import get_db
|
|
25
|
-
from dstack._internal.server.models import
|
|
27
|
+
from dstack._internal.server.models import (
|
|
28
|
+
InstanceModel,
|
|
29
|
+
ProjectModel,
|
|
30
|
+
UserModel,
|
|
31
|
+
VolumeAttachmentModel,
|
|
32
|
+
VolumeModel,
|
|
33
|
+
)
|
|
26
34
|
from dstack._internal.server.services import backends as backends_services
|
|
27
35
|
from dstack._internal.server.services.locking import (
|
|
28
36
|
get_locker,
|
|
29
37
|
string_to_lock_id,
|
|
30
38
|
)
|
|
39
|
+
from dstack._internal.server.services.pools import get_instance_provisioning_data
|
|
31
40
|
from dstack._internal.server.services.projects import list_project_models, list_user_project_models
|
|
32
41
|
from dstack._internal.utils import common, random_names
|
|
33
42
|
from dstack._internal.utils.logging import get_logger
|
|
@@ -106,8 +115,13 @@ async def list_projects_volume_models(
|
|
|
106
115
|
.order_by(*order_by)
|
|
107
116
|
.limit(limit)
|
|
108
117
|
.options(joinedload(VolumeModel.user))
|
|
118
|
+
.options(
|
|
119
|
+
joinedload(VolumeModel.attachments)
|
|
120
|
+
.joinedload(VolumeAttachmentModel.instance)
|
|
121
|
+
.joinedload(InstanceModel.fleet)
|
|
122
|
+
)
|
|
109
123
|
)
|
|
110
|
-
volume_models = list(res.scalars().all())
|
|
124
|
+
volume_models = list(res.unique().scalars().all())
|
|
111
125
|
return volume_models
|
|
112
126
|
|
|
113
127
|
|
|
@@ -134,9 +148,16 @@ async def list_project_volume_models(
|
|
|
134
148
|
if not include_deleted:
|
|
135
149
|
filters.append(VolumeModel.deleted == False)
|
|
136
150
|
res = await session.execute(
|
|
137
|
-
select(VolumeModel)
|
|
151
|
+
select(VolumeModel)
|
|
152
|
+
.where(*filters)
|
|
153
|
+
.options(joinedload(VolumeModel.user))
|
|
154
|
+
.options(
|
|
155
|
+
joinedload(VolumeModel.attachments)
|
|
156
|
+
.joinedload(VolumeAttachmentModel.instance)
|
|
157
|
+
.joinedload(InstanceModel.fleet)
|
|
158
|
+
)
|
|
138
159
|
)
|
|
139
|
-
return list(res.scalars().all())
|
|
160
|
+
return list(res.unique().scalars().all())
|
|
140
161
|
|
|
141
162
|
|
|
142
163
|
async def get_volume_by_name(
|
|
@@ -163,9 +184,16 @@ async def get_project_volume_model_by_name(
|
|
|
163
184
|
if not include_deleted:
|
|
164
185
|
filters.append(VolumeModel.deleted == False)
|
|
165
186
|
res = await session.execute(
|
|
166
|
-
select(VolumeModel)
|
|
187
|
+
select(VolumeModel)
|
|
188
|
+
.where(*filters)
|
|
189
|
+
.options(joinedload(VolumeModel.user))
|
|
190
|
+
.options(
|
|
191
|
+
joinedload(VolumeModel.attachments)
|
|
192
|
+
.joinedload(VolumeAttachmentModel.instance)
|
|
193
|
+
.joinedload(InstanceModel.fleet)
|
|
194
|
+
)
|
|
167
195
|
)
|
|
168
|
-
return res.scalar_one_or_none()
|
|
196
|
+
return res.unique().scalar_one_or_none()
|
|
169
197
|
|
|
170
198
|
|
|
171
199
|
async def create_volume(
|
|
@@ -205,10 +233,10 @@ async def create_volume(
|
|
|
205
233
|
project=project,
|
|
206
234
|
status=VolumeStatus.SUBMITTED,
|
|
207
235
|
configuration=configuration.json(),
|
|
236
|
+
attachments=[],
|
|
208
237
|
)
|
|
209
238
|
session.add(volume_model)
|
|
210
239
|
await session.commit()
|
|
211
|
-
await session.refresh(volume_model)
|
|
212
240
|
return volume_model_to_volume(volume_model)
|
|
213
241
|
|
|
214
242
|
|
|
@@ -234,13 +262,13 @@ async def delete_volumes(session: AsyncSession, project: ProjectModel, names: Li
|
|
|
234
262
|
VolumeModel.deleted == False,
|
|
235
263
|
)
|
|
236
264
|
.options(selectinload(VolumeModel.user))
|
|
237
|
-
.options(selectinload(VolumeModel.
|
|
265
|
+
.options(selectinload(VolumeModel.attachments))
|
|
238
266
|
.execution_options(populate_existing=True)
|
|
239
267
|
.with_for_update()
|
|
240
268
|
)
|
|
241
269
|
volume_models = res.scalars().unique().all()
|
|
242
270
|
for volume_model in volume_models:
|
|
243
|
-
if len(volume_model.
|
|
271
|
+
if len(volume_model.attachments) > 0:
|
|
244
272
|
raise ServerClientError(
|
|
245
273
|
f"Failed to delete volume {volume_model.name}. Volume is in use."
|
|
246
274
|
)
|
|
@@ -270,6 +298,15 @@ def volume_model_to_volume(volume_model: VolumeModel) -> Volume:
|
|
|
270
298
|
# Initially VolumeProvisionigData lacked backend
|
|
271
299
|
if vpd is not None and vpd.backend is None:
|
|
272
300
|
vpd.backend = configuration.backend
|
|
301
|
+
attachments = []
|
|
302
|
+
for volume_attachment_model in volume_model.attachments:
|
|
303
|
+
instance = volume_attachment_model.instance
|
|
304
|
+
attachments.append(
|
|
305
|
+
VolumeAttachment(
|
|
306
|
+
instance=instance_model_to_volume_instance(instance),
|
|
307
|
+
attachment_data=get_attachment_data(volume_attachment_model),
|
|
308
|
+
)
|
|
309
|
+
)
|
|
273
310
|
return Volume(
|
|
274
311
|
name=volume_model.name,
|
|
275
312
|
project_name=volume_model.project.name,
|
|
@@ -282,6 +319,7 @@ def volume_model_to_volume(volume_model: VolumeModel) -> Volume:
|
|
|
282
319
|
deleted=volume_model.deleted,
|
|
283
320
|
volume_id=vpd.volume_id if vpd is not None else None,
|
|
284
321
|
provisioning_data=vpd,
|
|
322
|
+
attachments=attachments,
|
|
285
323
|
attachment_data=vad,
|
|
286
324
|
id=volume_model.id,
|
|
287
325
|
)
|
|
@@ -303,6 +341,27 @@ def get_volume_attachment_data(volume_model: VolumeModel) -> Optional[VolumeAtta
|
|
|
303
341
|
return VolumeAttachmentData.__response__.parse_raw(volume_model.volume_attachment_data)
|
|
304
342
|
|
|
305
343
|
|
|
344
|
+
def get_attachment_data(
|
|
345
|
+
volume_attachment_model: VolumeAttachmentModel,
|
|
346
|
+
) -> Optional[VolumeAttachmentData]:
|
|
347
|
+
if volume_attachment_model.attachment_data is None:
|
|
348
|
+
return None
|
|
349
|
+
return VolumeAttachmentData.__response__.parse_raw(volume_attachment_model.attachment_data)
|
|
350
|
+
|
|
351
|
+
|
|
352
|
+
def instance_model_to_volume_instance(instance_model: InstanceModel) -> VolumeInstance:
|
|
353
|
+
instance_id = None
|
|
354
|
+
jpd = get_instance_provisioning_data(instance_model)
|
|
355
|
+
if jpd is not None:
|
|
356
|
+
instance_id = jpd.instance_id
|
|
357
|
+
return VolumeInstance(
|
|
358
|
+
name=instance_model.name,
|
|
359
|
+
fleet_name=instance_model.fleet.name if instance_model.fleet else None,
|
|
360
|
+
instance_num=instance_model.instance_num,
|
|
361
|
+
instance_id=instance_id,
|
|
362
|
+
)
|
|
363
|
+
|
|
364
|
+
|
|
306
365
|
async def generate_volume_name(session: AsyncSession, project: ProjectModel) -> str:
|
|
307
366
|
volume_models = await list_project_volume_models(session=session, project=project)
|
|
308
367
|
names = {v.name for v in volume_models}
|
|
@@ -55,7 +55,7 @@ from dstack._internal.core.models.runs import (
|
|
|
55
55
|
from dstack._internal.core.models.users import GlobalRole
|
|
56
56
|
from dstack._internal.core.models.volumes import (
|
|
57
57
|
Volume,
|
|
58
|
-
|
|
58
|
+
VolumeAttachment,
|
|
59
59
|
VolumeConfiguration,
|
|
60
60
|
VolumeProvisioningData,
|
|
61
61
|
VolumeStatus,
|
|
@@ -76,6 +76,7 @@ from dstack._internal.server.models import (
|
|
|
76
76
|
RepoModel,
|
|
77
77
|
RunModel,
|
|
78
78
|
UserModel,
|
|
79
|
+
VolumeAttachmentModel,
|
|
79
80
|
VolumeModel,
|
|
80
81
|
)
|
|
81
82
|
from dstack._internal.server.services.jobs import get_job_specs_from_run_spec
|
|
@@ -542,6 +543,9 @@ async def create_instance(
|
|
|
542
543
|
|
|
543
544
|
if volumes is None:
|
|
544
545
|
volumes = []
|
|
546
|
+
volume_attachments = []
|
|
547
|
+
for volume in volumes:
|
|
548
|
+
volume_attachments.append(VolumeAttachmentModel(volume=volume))
|
|
545
549
|
|
|
546
550
|
im = InstanceModel(
|
|
547
551
|
id=instance_id,
|
|
@@ -566,7 +570,7 @@ async def create_instance(
|
|
|
566
570
|
requirements=requirements.json(),
|
|
567
571
|
instance_configuration=instance_configuration.json(),
|
|
568
572
|
remote_connection_info=remote_connection_info.json() if remote_connection_info else None,
|
|
569
|
-
|
|
573
|
+
volume_attachments=volume_attachments,
|
|
570
574
|
total_blocks=total_blocks,
|
|
571
575
|
busy_blocks=busy_blocks,
|
|
572
576
|
)
|
|
@@ -587,6 +591,7 @@ def get_instance_offer_with_availability(
|
|
|
587
591
|
spot: bool = False,
|
|
588
592
|
blocks: int = 1,
|
|
589
593
|
total_blocks: int = 1,
|
|
594
|
+
availability_zones: Optional[List[str]] = None,
|
|
590
595
|
):
|
|
591
596
|
gpus = [Gpu(name="T4", memory_mib=16384, vendor=gpuhunt.AcceleratorVendor.NVIDIA)] * gpu_count
|
|
592
597
|
return InstanceOfferWithAvailability(
|
|
@@ -605,6 +610,7 @@ def get_instance_offer_with_availability(
|
|
|
605
610
|
region=region,
|
|
606
611
|
price=1,
|
|
607
612
|
availability=InstanceAvailability.AVAILABLE,
|
|
613
|
+
availability_zones=availability_zones,
|
|
608
614
|
blocks=blocks,
|
|
609
615
|
total_blocks=total_blocks,
|
|
610
616
|
)
|
|
@@ -669,7 +675,7 @@ async def create_volume(
|
|
|
669
675
|
volume_provisioning_data=volume_provisioning_data.json()
|
|
670
676
|
if volume_provisioning_data
|
|
671
677
|
else None,
|
|
672
|
-
|
|
678
|
+
attachments=[],
|
|
673
679
|
deleted_at=deleted_at,
|
|
674
680
|
deleted=True if deleted_at else False,
|
|
675
681
|
)
|
|
@@ -691,16 +697,14 @@ def get_volume(
|
|
|
691
697
|
deleted: bool = False,
|
|
692
698
|
volume_id: Optional[str] = None,
|
|
693
699
|
provisioning_data: Optional[VolumeProvisioningData] = None,
|
|
694
|
-
|
|
695
|
-
device_name: Optional[str] = None,
|
|
700
|
+
attachments: Optional[List[VolumeAttachment]] = None,
|
|
696
701
|
) -> Volume:
|
|
697
702
|
if id_ is None:
|
|
698
703
|
id_ = uuid.uuid4()
|
|
699
704
|
if configuration is None:
|
|
700
705
|
configuration = get_volume_configuration()
|
|
701
|
-
if
|
|
702
|
-
|
|
703
|
-
attachment_data = VolumeAttachmentData(device_name=device_name)
|
|
706
|
+
if attachments is None:
|
|
707
|
+
attachments = []
|
|
704
708
|
return Volume(
|
|
705
709
|
id=id_,
|
|
706
710
|
name=name,
|
|
@@ -714,7 +718,7 @@ def get_volume(
|
|
|
714
718
|
deleted=deleted,
|
|
715
719
|
volume_id=volume_id,
|
|
716
720
|
provisioning_data=provisioning_data,
|
|
717
|
-
|
|
721
|
+
attachments=attachments,
|
|
718
722
|
)
|
|
719
723
|
|
|
720
724
|
|
dstack/version.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
dstack/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
-
dstack/version.py,sha256=
|
|
2
|
+
dstack/version.py,sha256=2vyD60hf6Ar7fKjyGNRtiogwJDCRrkoglz7oYuLU-uY,65
|
|
3
3
|
dstack/_internal/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
4
|
dstack/_internal/compat.py,sha256=bF9U9fTMfL8UVhCouedoUSTYFl7UAOiU0WXrnRoByxw,40
|
|
5
5
|
dstack/_internal/settings.py,sha256=8XODoSW2joaEndvZxuHUPSFK85sGgJ7fVL976isYeJM,557
|
|
@@ -38,14 +38,14 @@ dstack/_internal/cli/utils/gateway.py,sha256=jMytH6u3x8hctMhm9bcmXLJxSgTXmpW8M9a
|
|
|
38
38
|
dstack/_internal/cli/utils/rich.py,sha256=Gx1MJU929kMKsbdo9qF7XHARNta2426Ssb-xMLVhwbQ,5710
|
|
39
39
|
dstack/_internal/cli/utils/run.py,sha256=4NDhlcdE4bccQ4gWzhZ2EP8tHryZt4eI3BBho425VOA,7737
|
|
40
40
|
dstack/_internal/cli/utils/updates.py,sha256=9KQcm_TEE_PiU0yc5WH4xRse0WIeHOubi9Et55odgvk,2601
|
|
41
|
-
dstack/_internal/cli/utils/volume.py,sha256=
|
|
41
|
+
dstack/_internal/cli/utils/volume.py,sha256=mU9I06dVMFbpjfkefxrZNoSWadKLoib3U14rHudNQN4,1975
|
|
42
42
|
dstack/_internal/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
43
43
|
dstack/_internal/core/consts.py,sha256=c1Yd5UY6Qx7KeuYgloXWncWhMsYj6TqwlElda7NtB98,254
|
|
44
44
|
dstack/_internal/core/errors.py,sha256=UvqMIBVHG1NIUP0w0g5dWjnxOz37sfFi4lh4yuYK0vw,2793
|
|
45
45
|
dstack/_internal/core/backends/__init__.py,sha256=P7uX9QYj-aWSHOub1vIwr-MVERVCwTi8pcG4MQVuEYw,958
|
|
46
46
|
dstack/_internal/core/backends/aws/__init__.py,sha256=gGXM9op3UJ3-OGDjNr4ywa_fNf--oywRbrOGUH2tTDA,850
|
|
47
47
|
dstack/_internal/core/backends/aws/auth.py,sha256=lRBwNUdEWMWlblDnFSGlIcNkZMY2tSjapdq1OjwollU,1253
|
|
48
|
-
dstack/_internal/core/backends/aws/compute.py,sha256=
|
|
48
|
+
dstack/_internal/core/backends/aws/compute.py,sha256=I7DyBNc9wFqMQ9-9IxX3rmIyNzq4hCS5hT8uorSn9_E,35308
|
|
49
49
|
dstack/_internal/core/backends/aws/config.py,sha256=bd4juOaiqsUsWeorIgqCW0xNigCFIRQIvaRxEHyhpwg,533
|
|
50
50
|
dstack/_internal/core/backends/aws/resources.py,sha256=yKsMMLO4HMRTWero8cLDxtavWvqcne_y9VDXVH9G1lE,22551
|
|
51
51
|
dstack/_internal/core/backends/azure/__init__.py,sha256=J-mWp413v0DQFaTochlvMJXlGf8ukQCH_6oGuYFR31U,718
|
|
@@ -68,7 +68,7 @@ dstack/_internal/core/backends/datacrunch/compute.py,sha256=gyOftmUdmS9fMqpyew0P
|
|
|
68
68
|
dstack/_internal/core/backends/datacrunch/config.py,sha256=bShWTAb02PYP8fuBz7H7r-YhRkhy6_yfD0nuaKd9xd4,281
|
|
69
69
|
dstack/_internal/core/backends/gcp/__init__.py,sha256=nxhPNTGd1pPag2DwBRKg3X5gEKlh32p7a9Yfyi7-d5k,546
|
|
70
70
|
dstack/_internal/core/backends/gcp/auth.py,sha256=AL5i7VtXvMboTCk-dzvNykaogYV31xAYfEivXxzOD_k,1832
|
|
71
|
-
dstack/_internal/core/backends/gcp/compute.py,sha256=
|
|
71
|
+
dstack/_internal/core/backends/gcp/compute.py,sha256=ksGatfOjPp78kTIpuxbEX3awMv9Wy2ErLX4FbGlrOI4,36001
|
|
72
72
|
dstack/_internal/core/backends/gcp/config.py,sha256=AjNHgIsDqB5aKdyFXTKG9wNO2d3lgNyJW4Dk5Yb-LL4,722
|
|
73
73
|
dstack/_internal/core/backends/gcp/resources.py,sha256=6khFYRZwMrjRxVAoHav3OsKFSVw-tuLVkJ_FzQCY8EI,14741
|
|
74
74
|
dstack/_internal/core/backends/kubernetes/__init__.py,sha256=MpuT3Dxt2ZwZpAQomE_fXUDmgHBmfP8xvUP1YMAKTJQ,573
|
|
@@ -126,13 +126,13 @@ dstack/_internal/core/models/pools.py,sha256=SmxNQsSYolUMkraLi0BvEXDacuhp1cvbGQn
|
|
|
126
126
|
dstack/_internal/core/models/profiles.py,sha256=Y0qsIV0DvvI-YxtcMLqmsrqulGKzJsE_0SdWU2Wusv8,8208
|
|
127
127
|
dstack/_internal/core/models/projects.py,sha256=hY3rhLWkuDRsavAdNvQaK6IhnTr7yBHTmNwy9k7zjVE,643
|
|
128
128
|
dstack/_internal/core/models/resources.py,sha256=AzBqGEZLHmg-HpjQtcb_W4pJQRxRtDyeuiHO4berdBA,12408
|
|
129
|
-
dstack/_internal/core/models/runs.py,sha256=
|
|
129
|
+
dstack/_internal/core/models/runs.py,sha256=ziWnqFRL1hORWJ10evwxLySAe9umiP7kTc3IUvEniSc,17940
|
|
130
130
|
dstack/_internal/core/models/secrets.py,sha256=OlnBI8ESBnpjSqB0-Vr3z8JcqB2Ydfiwo8IJUuM5jAc,219
|
|
131
131
|
dstack/_internal/core/models/server.py,sha256=Hkc1v2s3KOiwslsWVmhUOAzcSeREoG-HD1SzSX9WUGg,152
|
|
132
132
|
dstack/_internal/core/models/services.py,sha256=2Hpi7j0Q1shaf_0wd0C0044AJAmuYi-D3qx3PH849oI,3076
|
|
133
133
|
dstack/_internal/core/models/unix.py,sha256=KxnSQELnkAjjuUgYcQKVkf-UAbYREBD8WCWDvHfOkuA,1915
|
|
134
134
|
dstack/_internal/core/models/users.py,sha256=o_rd0GAmd6jufypVUs9P12NRri3rgAPDt-KxnqNNsGw,703
|
|
135
|
-
dstack/_internal/core/models/volumes.py,sha256=
|
|
135
|
+
dstack/_internal/core/models/volumes.py,sha256=ZebkSybGXmnPQHjsDCWVofHavjwjLIovssmpXnLW6nU,6207
|
|
136
136
|
dstack/_internal/core/models/backends/__init__.py,sha256=iPMAv4j7gpHc0cjt3SxzQGb-sywms8LUXt7IjtKNPnM,5589
|
|
137
137
|
dstack/_internal/core/models/backends/aws.py,sha256=H0RB7pTVb7vjW_-MDpBBwPLbAoKDRtYFHe_n4ppXz6w,2463
|
|
138
138
|
dstack/_internal/core/models/backends/azure.py,sha256=OhK3HBvI_ZfLmKVxlnm7AowWOlarp6QXb3tbcbFoACw,2076
|
|
@@ -223,20 +223,20 @@ dstack/_internal/server/app.py,sha256=pPto7JaBEkwvPF2FR8sqDzwIyMovI_85xk6WXfnnCY
|
|
|
223
223
|
dstack/_internal/server/db.py,sha256=WjuqmjG3QAZmSMCeUaJ_ynbowlHuNAvYCZO649cTPHc,3210
|
|
224
224
|
dstack/_internal/server/deps.py,sha256=31e8SU_ogPJWHIDLkgl7cuC_5V91xbJoLyAj17VanfM,670
|
|
225
225
|
dstack/_internal/server/main.py,sha256=kztKhCYNoHSDyJJQScWfZXE0naNleJOCQULW6dd8SGw,109
|
|
226
|
-
dstack/_internal/server/models.py,sha256=
|
|
226
|
+
dstack/_internal/server/models.py,sha256=VKh_lfgGUlc0Xy_CGo02IDgwPRp3membAJg07jm27j4,27405
|
|
227
227
|
dstack/_internal/server/settings.py,sha256=tEPw0xIltvW4TpLBA-OzKRM_PmvDuD4vuXCo7ITyzpo,3067
|
|
228
228
|
dstack/_internal/server/background/__init__.py,sha256=jNDwTgQwKhK1NYl0RJaKU4mwKIMOSIxPTKVyhizU1PM,3436
|
|
229
229
|
dstack/_internal/server/background/tasks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
230
230
|
dstack/_internal/server/background/tasks/process_fleets.py,sha256=lKXUvN_b7DNjD3psHzyCt_JYsTxPFuQ86iXi8fj8GkM,3202
|
|
231
231
|
dstack/_internal/server/background/tasks/process_gateways.py,sha256=KN5n9r0cKizJ3oGpeLsv3euZKZOMf-02X0Sv09GE8N8,7141
|
|
232
|
-
dstack/_internal/server/background/tasks/process_instances.py,sha256=
|
|
232
|
+
dstack/_internal/server/background/tasks/process_instances.py,sha256=HaOTfcBcrwlRhHHbpeRflCcf3VYW-OkE6SB74SxvwXQ,37369
|
|
233
233
|
dstack/_internal/server/background/tasks/process_metrics.py,sha256=BPv0S7pmMX91vObZiW51AJiNR0ULIj-OQlo5n97KISY,5328
|
|
234
234
|
dstack/_internal/server/background/tasks/process_placement_groups.py,sha256=DZctiMF2TXKbYeygoz--ZiC9MXVL1sQJgq0oqRIc7hg,3858
|
|
235
|
-
dstack/_internal/server/background/tasks/process_running_jobs.py,sha256=
|
|
235
|
+
dstack/_internal/server/background/tasks/process_running_jobs.py,sha256=FAIwXKIOUbVM-svKo7aoAF9DdxIhcejQJfg6gs0z83k,30108
|
|
236
236
|
dstack/_internal/server/background/tasks/process_runs.py,sha256=JWJqMzXXqvwQSxyKs4bKH2aBP8YQbiyO4tuwyMPVduk,16673
|
|
237
|
-
dstack/_internal/server/background/tasks/process_submitted_jobs.py,sha256=
|
|
238
|
-
dstack/_internal/server/background/tasks/process_terminating_jobs.py,sha256=
|
|
239
|
-
dstack/_internal/server/background/tasks/process_volumes.py,sha256=
|
|
237
|
+
dstack/_internal/server/background/tasks/process_submitted_jobs.py,sha256=xv1aW2umlOdbdZn4TOvlhl6td3Uam378yIwosfSO9ks,27022
|
|
238
|
+
dstack/_internal/server/background/tasks/process_terminating_jobs.py,sha256=A8J6JabVih1nHl3Kgyaoh7eaKPywicZe7vx-4V_uvgk,4033
|
|
239
|
+
dstack/_internal/server/background/tasks/process_volumes.py,sha256=YafZml-b-bD7M6S0UmY-rLV-pIIX-SdzuyaErqxrnyk,4939
|
|
240
240
|
dstack/_internal/server/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
241
241
|
dstack/_internal/server/migrations/env.py,sha256=RuhcN-CST86VzMatjqBMdYcG0fGGMZl_o1YgZTL-WDw,2831
|
|
242
242
|
dstack/_internal/server/migrations/versions/065588ec72b8_add_vultr_to_backendtype_enum.py,sha256=wSdI_HWGUFgczhOPyoP6BTPmDbN3KmjokHVpZJGsq4Q,2112
|
|
@@ -277,6 +277,7 @@ dstack/_internal/server/migrations/versions/99b4c8c954ea_add_termination_reason_
|
|
|
277
277
|
dstack/_internal/server/migrations/versions/9eea6af28e10_added_fail_reason_for_instancemodel.py,sha256=n0iWQ3L1DWQqPIT-IRs9TR74psf-ZDjcYvSIfn80etY,1027
|
|
278
278
|
dstack/_internal/server/migrations/versions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
279
279
|
dstack/_internal/server/migrations/versions/a060e2440936_.py,sha256=4wXIln1yzEowe-1_xFRJFGfaVIwkwlpAO9RlLeVQ-uY,8016
|
|
280
|
+
dstack/_internal/server/migrations/versions/a751ef183f27_move_attachment_data_to_volumes_.py,sha256=befGXlRV7vP6u3VIyf7nMslyBHVAZuFbomQpmc7phRs,1023
|
|
280
281
|
dstack/_internal/server/migrations/versions/a7b46c073fa1_add_placementgroupmodel.py,sha256=fXYI21V43UmHcIpq7KfD8Ggcjy_l4I_hfXWhB0SnSBM,2078
|
|
281
282
|
dstack/_internal/server/migrations/versions/afbc600ff2b2_add_created_at_to_usermodel_and_.py,sha256=qRDvCdBaTjL82sdZN2GTWq0JCF2PZU-jFANzCJnM4Bw,3705
|
|
282
283
|
dstack/_internal/server/migrations/versions/b4d6ad60db08_add_instancemodel_unreachable.py,sha256=rnmLqt_pzNtqMqcmzXIPZxs5WxDE7ieAdI6SnKUFjqM,1038
|
|
@@ -333,21 +334,21 @@ dstack/_internal/server/security/permissions.py,sha256=K756I8fnBLBrq4PZwz1ttt74H
|
|
|
333
334
|
dstack/_internal/server/services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
334
335
|
dstack/_internal/server/services/config.py,sha256=b7m2wkVjtXDR46WMgYLw2uun9orM9lxXjnDp53oeASM,29525
|
|
335
336
|
dstack/_internal/server/services/docker.py,sha256=3EcYPiVsrNBGDQYOb60QJ241mzTT6lJROYQXIwt-8dk,5351
|
|
336
|
-
dstack/_internal/server/services/fleets.py,sha256=
|
|
337
|
+
dstack/_internal/server/services/fleets.py,sha256=h5LL8FGOZMOl0kzLycP36U6k3SWl_bSnSn7oFg8ubQY,28980
|
|
337
338
|
dstack/_internal/server/services/locking.py,sha256=UV5kc-BgROBuNDpBrp8jkcf-fHPOpHLc8JufL-8mbN8,2453
|
|
338
339
|
dstack/_internal/server/services/logging.py,sha256=Nu1628kW2hqB__N0Eyr07wGWjVWxfyJnczonTJ72kSM,417
|
|
339
340
|
dstack/_internal/server/services/logs.py,sha256=53pymPDaM9-xXHFzCyEHdvM49JPTpsLI2aPTSP5zaPo,20090
|
|
340
341
|
dstack/_internal/server/services/metrics.py,sha256=_YmAQ_oCzzklgk_O5iSJDZJhRk9rBqx8REkPcRQUTAo,3490
|
|
341
|
-
dstack/_internal/server/services/offers.py,sha256=
|
|
342
|
+
dstack/_internal/server/services/offers.py,sha256=GIaICztEu4zbcpIGHvNsfMVYmPvoYg5zcQ0apHNdgBw,6954
|
|
342
343
|
dstack/_internal/server/services/permissions.py,sha256=l7Ngdelmn65vjw13NcOdaC6lBYMRuSw6FbHzYwdK3nE,1005
|
|
343
344
|
dstack/_internal/server/services/placement.py,sha256=DWZ8-iAE3o0J0xaHikuJYZzpuBiq7lj41LiAP1PfoEs,1773
|
|
344
|
-
dstack/_internal/server/services/pools.py,sha256=
|
|
345
|
+
dstack/_internal/server/services/pools.py,sha256=yDlNJn219satSuoxRmlxDG-BPrK0j7MdmGNa-HMyCsk,28886
|
|
345
346
|
dstack/_internal/server/services/projects.py,sha256=HWOnFOC6LmvbjDzRKADv7tXKIDWthbO11zrsHU7vkew,14709
|
|
346
347
|
dstack/_internal/server/services/repos.py,sha256=f9ztN7jz_2gvD9hXF5sJwWDVyG2-NHRfjIdSukowPh8,9342
|
|
347
348
|
dstack/_internal/server/services/runs.py,sha256=3m9oYKq08QQF1GlaOa6_2nYp9SMYoqvfjVnO3-fpTGY,36045
|
|
348
349
|
dstack/_internal/server/services/storage.py,sha256=6I0xI_3_RpJNbKZwHjDnjrEwXGdHfiaeb5li15T-M1I,1884
|
|
349
350
|
dstack/_internal/server/services/users.py,sha256=L-exfxHdhj3TKX-gSjezHrYK6tnrt5qsQs-zZng1tUI,7123
|
|
350
|
-
dstack/_internal/server/services/volumes.py,sha256=
|
|
351
|
+
dstack/_internal/server/services/volumes.py,sha256=UX-fqC3c240aG6EbdtVsXrJQbkF0O06IFZNtg6bA_tE,14551
|
|
351
352
|
dstack/_internal/server/services/backends/__init__.py,sha256=Q8Ju0Shf2RAlIdi1CapJNUKOdUAFeRnxhNYti6GZiww,14923
|
|
352
353
|
dstack/_internal/server/services/backends/handlers.py,sha256=j-MhBxrpdepoDG7f2tApjFnE23RVO5I15-hxHyOWnew,3251
|
|
353
354
|
dstack/_internal/server/services/backends/configurators/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -374,7 +375,7 @@ dstack/_internal/server/services/gateways/__init__.py,sha256=ceTzXRWu-pVghze9New
|
|
|
374
375
|
dstack/_internal/server/services/gateways/client.py,sha256=1PH9gUjRkHegp37B27pjBVoPFk64KjxcE30eEPBTLM0,7321
|
|
375
376
|
dstack/_internal/server/services/gateways/connection.py,sha256=ot3lV85XdmCT45vBWeyj57nLPcLPNm316zu3jMyeWjA,5625
|
|
376
377
|
dstack/_internal/server/services/gateways/pool.py,sha256=0LclTl1tyx-doS78LeaAKjr-SMp98zuwh5f9s06JSd0,1914
|
|
377
|
-
dstack/_internal/server/services/jobs/__init__.py,sha256=
|
|
378
|
+
dstack/_internal/server/services/jobs/__init__.py,sha256=zxKGDUo_6Sjoh3VGMQVrxQn9OkwgJQJXeKo3DZWkRI8,25283
|
|
378
379
|
dstack/_internal/server/services/jobs/configurators/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
379
380
|
dstack/_internal/server/services/jobs/configurators/base.py,sha256=I21dp1P9XC49NNJL_bfihwXfhFd6G-yQXYFYk-EJPEI,10306
|
|
380
381
|
dstack/_internal/server/services/jobs/configurators/dev.py,sha256=2EEtfOpNXP5d9b3ZErE3dA3Co8aAAv1fbx9wAjRZpGY,2018
|
|
@@ -392,7 +393,7 @@ dstack/_internal/server/services/proxy/routers/service_proxy.py,sha256=8rsuenv9L
|
|
|
392
393
|
dstack/_internal/server/services/proxy/services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
393
394
|
dstack/_internal/server/services/proxy/services/service_proxy.py,sha256=4JrSxHqhBYqU1oENii89Db-bzkFWExYrOy-0mNEhWBs,4879
|
|
394
395
|
dstack/_internal/server/services/runner/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
395
|
-
dstack/_internal/server/services/runner/client.py,sha256=
|
|
396
|
+
dstack/_internal/server/services/runner/client.py,sha256=lQBQoUIMtKviSSQV9rx8VKfWXlRswGJOEI0TF7QV_oA,14961
|
|
396
397
|
dstack/_internal/server/services/runner/ssh.py,sha256=H-X0015ZPwYq5tc31ytFF1uNaUAr9itAsABI2oPJWrk,5017
|
|
397
398
|
dstack/_internal/server/services/services/__init__.py,sha256=-kbk6Qb0mGImhNtYhG7JRsmyc0rKGl0A4rRuN1Wq2bA,10617
|
|
398
399
|
dstack/_internal/server/services/services/autoscalers.py,sha256=0o_w9La-ex_P3VKG88w_XN3hkLkzryv5l1cH3pkZyAE,4315
|
|
@@ -502,7 +503,7 @@ dstack/_internal/server/statics/static/media/logo.f602feeb138844eda97c8cb6414614
|
|
|
502
503
|
dstack/_internal/server/statics/static/media/okta.12f178e6873a1100965f2a4dbd18fcec.svg,sha256=KqFI05gQM135zC1plF1WBRF2F7CyKL7km97WKsZjAHI,319
|
|
503
504
|
dstack/_internal/server/statics/static/media/theme.3994c817bb7dda191c1c9640dee0bf42.svg,sha256=ZxFFBVZWuRLqmWH4zhwGLNtKjOzHj-5MGJRunFAtu1I,561
|
|
504
505
|
dstack/_internal/server/testing/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
505
|
-
dstack/_internal/server/testing/common.py,sha256=
|
|
506
|
+
dstack/_internal/server/testing/common.py,sha256=xwIk9mNec_9OBvJYw_RH9kdOou0Hs8S0qxMor9SH2x4,28949
|
|
506
507
|
dstack/_internal/server/testing/conf.py,sha256=-zhujfFjTHNfQDOK-hBck32By11c_kC0OeinB3esQGg,1902
|
|
507
508
|
dstack/_internal/server/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
508
509
|
dstack/_internal/server/utils/common.py,sha256=PbjXtqYy1taKXpyG5ys8cIrz9MXqc9dBAsR_9D1brrk,1414
|
|
@@ -613,11 +614,11 @@ tests/_internal/server/background/tasks/test_process_gateways.py,sha256=h7jzDFQp
|
|
|
613
614
|
tests/_internal/server/background/tasks/test_process_instances.py,sha256=-ATbgOT8XAeqGmPn4XPlSJzxnrm0haAJhX13nWOBOtM,24816
|
|
614
615
|
tests/_internal/server/background/tasks/test_process_metrics.py,sha256=eirq386mVZqX_PqctuX7CxO38Prwy8RH2UesYXo3CnQ,5083
|
|
615
616
|
tests/_internal/server/background/tasks/test_process_placement_groups.py,sha256=shHqZvS8QoNwQe8J29-aHk2X2HqX-gsxcQiZevU8yuY,1528
|
|
616
|
-
tests/_internal/server/background/tasks/test_process_running_jobs.py,sha256=
|
|
617
|
+
tests/_internal/server/background/tasks/test_process_running_jobs.py,sha256=zm0eGL3MY5H7YAZuKO0fTqyU0Tb-W2lGniHN6XwOXoE,25542
|
|
617
618
|
tests/_internal/server/background/tasks/test_process_runs.py,sha256=Yv6f2CDZ-ejDGo7uOKyyAGxYLsvqyjNo4Zw1cCQbjgM,14489
|
|
618
|
-
tests/_internal/server/background/tasks/test_process_submitted_jobs.py,sha256=
|
|
619
|
+
tests/_internal/server/background/tasks/test_process_submitted_jobs.py,sha256=Sf4aDa1ZYw5Sz3xAw8K0hoI-VDesv7Ew3gZdAzQvj_4,24451
|
|
619
620
|
tests/_internal/server/background/tasks/test_process_submitted_volumes.py,sha256=njfRDdDzVtDL8rech_004Wf5z5PpoQVWFufKh1yUyYY,2171
|
|
620
|
-
tests/_internal/server/background/tasks/test_process_terminating_jobs.py,sha256=
|
|
621
|
+
tests/_internal/server/background/tasks/test_process_terminating_jobs.py,sha256=VZsfP1NVxkcLSNWfEXDFe_vQZUQfuG0B5i-krXKP_IQ,14147
|
|
621
622
|
tests/_internal/server/routers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
622
623
|
tests/_internal/server/routers/test_backends.py,sha256=4bY8oMMKB3xIRWUfVIUcI4dhDz1ukcpEeWOLllxmPUw,65231
|
|
623
624
|
tests/_internal/server/routers/test_fleets.py,sha256=ap3Jjg2iiwuklosu2_-xx-cJBlM6uZN5CQfGudORPf0,35105
|
|
@@ -631,13 +632,14 @@ tests/_internal/server/routers/test_repos.py,sha256=4O4mCDlAPh8xJU_XWtwLhFWRkoTx
|
|
|
631
632
|
tests/_internal/server/routers/test_runs.py,sha256=t6tuvN8JHKSKgd_PRTlPo3VzsJ3aE_EmW9f8cczxQ4M,71547
|
|
632
633
|
tests/_internal/server/routers/test_server.py,sha256=ROkuRNNJEkMQuK8guZ3Qy3iRRfiWvPIJJJDc09BI0D4,489
|
|
633
634
|
tests/_internal/server/routers/test_users.py,sha256=5QSLvfn9SroGsZoBGmSTEaaqJcdEO8EUUy_YuvLL8ss,12787
|
|
634
|
-
tests/_internal/server/routers/test_volumes.py,sha256=
|
|
635
|
+
tests/_internal/server/routers/test_volumes.py,sha256=fVv7sVo9POFImal9Mlkaw8CJOAR67S_eYHxIReHebBU,16241
|
|
635
636
|
tests/_internal/server/services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
636
637
|
tests/_internal/server/services/test_config.py,sha256=KfPyYSSsLaQszBAgqYeM2Tt5YkRiV-at0ik86ecdrtE,5168
|
|
637
638
|
tests/_internal/server/services/test_docker.py,sha256=QsnoVJUnvzcd1Tpw0UtKXtDSCr9nh_jmtVSkOi7J4ug,5628
|
|
638
639
|
tests/_internal/server/services/test_fleets.py,sha256=WqK9Bs3Nfew45n4WunZhvIvCw0VHJ2w5t0-4CakxFgU,8222
|
|
639
640
|
tests/_internal/server/services/test_logs.py,sha256=QmaI07u9O0czwH8J2eZO3mOYnutAtIrDTUrF9CJLdwU,29647
|
|
640
|
-
tests/_internal/server/services/
|
|
641
|
+
tests/_internal/server/services/test_offers.py,sha256=t0nQNjjm-fvIqHIOA_99hokrdTXwpYrgzjaQjqJXs8w,7814
|
|
642
|
+
tests/_internal/server/services/test_pools.py,sha256=aPF4R6_VCeDR4AcjQ0H2J1BKivoVs-JUNQBJZ-IYdPg,7436
|
|
641
643
|
tests/_internal/server/services/test_repos.py,sha256=o2D0xmOPYaiwDq6nNJNtqYMSuSz_xKJ_ZChVOvWIhJY,14289
|
|
642
644
|
tests/_internal/server/services/test_runs.py,sha256=8frDxa3NTJzXir6fJTXRLm_0B_jUd36qV66DgHvRdDU,9289
|
|
643
645
|
tests/_internal/server/services/encryption/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -651,7 +653,7 @@ tests/_internal/server/services/proxy/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCe
|
|
|
651
653
|
tests/_internal/server/services/proxy/routers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
652
654
|
tests/_internal/server/services/proxy/routers/test_service_proxy.py,sha256=cGyBwfSgT268CRhkgpTEIM3O1U9z8tSNTYjHQrn3e0E,9843
|
|
653
655
|
tests/_internal/server/services/runner/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
654
|
-
tests/_internal/server/services/runner/test_client.py,sha256=
|
|
656
|
+
tests/_internal/server/services/runner/test_client.py,sha256=azCFqMipDCEhoTy4pjq3L5me4SD-mk0ldHTEQ6N6uu8,16855
|
|
655
657
|
tests/_internal/server/services/services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
656
658
|
tests/_internal/server/services/services/test_autoscalers.py,sha256=YMi4W5gKFOpEdutc2Fli1L1DIUxCJLHE7ji-CJoiVac,3986
|
|
657
659
|
tests/_internal/server/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -667,9 +669,9 @@ tests/_internal/utils/test_path.py,sha256=rzS-1YCxsFUocBe42dghLOMFNymPruGrA7bqFZ
|
|
|
667
669
|
tests/_internal/utils/test_ssh.py,sha256=V-cBFPhD--9eM9d1uQQgpj2gnYLA3c43f4cX9uJ6E-U,1743
|
|
668
670
|
tests/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
669
671
|
tests/api/test_utils.py,sha256=SSSqHcNE5cZVqDq4n2sKZthRoXaZ_Bx7z1AAN5xTM9s,391
|
|
670
|
-
dstack-0.18.
|
|
671
|
-
dstack-0.18.
|
|
672
|
-
dstack-0.18.
|
|
673
|
-
dstack-0.18.
|
|
674
|
-
dstack-0.18.
|
|
675
|
-
dstack-0.18.
|
|
672
|
+
dstack-0.18.42.dist-info/LICENSE.md,sha256=qDABaRGjSKVOib1U8viw2P_96sIK7Puo426784oD9f8,15976
|
|
673
|
+
dstack-0.18.42.dist-info/METADATA,sha256=vSyb16zzc0XeDvb0drJPn91GJqIajnyIKNc8RY3THtE,17690
|
|
674
|
+
dstack-0.18.42.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
|
|
675
|
+
dstack-0.18.42.dist-info/entry_points.txt,sha256=GnLrMS8hx3rWAySQjA7tPNhtixV6a-brRkmal1PKoHc,58
|
|
676
|
+
dstack-0.18.42.dist-info/top_level.txt,sha256=3BrIO1zrqxT9P20ymhRM6k15meZXzbPL6ykBlDZG2_k,13
|
|
677
|
+
dstack-0.18.42.dist-info/RECORD,,
|
|
@@ -349,6 +349,7 @@ class TestProcessRunningJobs:
|
|
|
349
349
|
host_ssh_user="ubuntu",
|
|
350
350
|
host_ssh_keys=["user_ssh_key"],
|
|
351
351
|
container_ssh_keys=[project_ssh_pub_key, "user_ssh_key"],
|
|
352
|
+
instance_id=job_provisioning_data.instance_id,
|
|
352
353
|
)
|
|
353
354
|
await session.refresh(job)
|
|
354
355
|
assert job is not None
|
|
@@ -27,7 +27,7 @@ from dstack._internal.core.models.volumes import (
|
|
|
27
27
|
VolumeStatus,
|
|
28
28
|
)
|
|
29
29
|
from dstack._internal.server.background.tasks.process_submitted_jobs import process_submitted_jobs
|
|
30
|
-
from dstack._internal.server.models import InstanceModel, JobModel
|
|
30
|
+
from dstack._internal.server.models import InstanceModel, JobModel, VolumeAttachmentModel
|
|
31
31
|
from dstack._internal.server.testing.common import (
|
|
32
32
|
create_fleet,
|
|
33
33
|
create_instance,
|
|
@@ -515,7 +515,9 @@ class TestProcessSubmittedJobs:
|
|
|
515
515
|
await session.refresh(instance)
|
|
516
516
|
res = await session.execute(
|
|
517
517
|
select(JobModel).options(
|
|
518
|
-
joinedload(JobModel.instance)
|
|
518
|
+
joinedload(JobModel.instance)
|
|
519
|
+
.joinedload(InstanceModel.volume_attachments)
|
|
520
|
+
.joinedload(VolumeAttachmentModel.volume)
|
|
519
521
|
)
|
|
520
522
|
)
|
|
521
523
|
job = res.unique().scalar_one()
|
|
@@ -523,7 +525,7 @@ class TestProcessSubmittedJobs:
|
|
|
523
525
|
assert (
|
|
524
526
|
job.instance_assigned and job.instance is not None and job.instance.id == instance.id
|
|
525
527
|
)
|
|
526
|
-
assert job.instance.
|
|
528
|
+
assert job.instance.volume_attachments[0].volume == volume
|
|
527
529
|
|
|
528
530
|
@pytest.mark.asyncio
|
|
529
531
|
@pytest.mark.parametrize("test_db", ["sqlite", "postgres"], indirect=True)
|
|
@@ -13,7 +13,7 @@ from dstack._internal.core.models.volumes import VolumeStatus
|
|
|
13
13
|
from dstack._internal.server.background.tasks.process_terminating_jobs import (
|
|
14
14
|
process_terminating_jobs,
|
|
15
15
|
)
|
|
16
|
-
from dstack._internal.server.models import InstanceModel, JobModel
|
|
16
|
+
from dstack._internal.server.models import InstanceModel, JobModel, VolumeAttachmentModel
|
|
17
17
|
from dstack._internal.server.services.volumes import volume_model_to_volume
|
|
18
18
|
from dstack._internal.server.testing.common import (
|
|
19
19
|
create_instance,
|
|
@@ -176,7 +176,7 @@ class TestProcessTerminatingJobs:
|
|
|
176
176
|
# so that stuck volumes don't prevent the instance from terminating.
|
|
177
177
|
assert job.instance is None
|
|
178
178
|
assert job.volumes_detached_at is not None
|
|
179
|
-
assert len(instance.
|
|
179
|
+
assert len(instance.volume_attachments) == 1
|
|
180
180
|
|
|
181
181
|
# Force detach called
|
|
182
182
|
with (
|
|
@@ -214,11 +214,11 @@ class TestProcessTerminatingJobs:
|
|
|
214
214
|
res = await session.execute(select(JobModel).options(joinedload(JobModel.instance)))
|
|
215
215
|
job = res.unique().scalar_one()
|
|
216
216
|
res = await session.execute(
|
|
217
|
-
select(InstanceModel).options(joinedload(InstanceModel.
|
|
217
|
+
select(InstanceModel).options(joinedload(InstanceModel.volume_attachments))
|
|
218
218
|
)
|
|
219
219
|
instance = res.unique().scalar_one()
|
|
220
220
|
assert job.status == JobStatus.TERMINATED
|
|
221
|
-
assert len(instance.
|
|
221
|
+
assert len(instance.volume_attachments) == 0
|
|
222
222
|
|
|
223
223
|
async def test_terminates_job_on_shared_instance(self, session: AsyncSession):
|
|
224
224
|
project = await create_project(session)
|
|
@@ -330,7 +330,12 @@ class TestProcessTerminatingJobs:
|
|
|
330
330
|
await session.refresh(instance)
|
|
331
331
|
assert job.status == JobStatus.TERMINATED
|
|
332
332
|
res = await session.execute(
|
|
333
|
-
select(InstanceModel).options(
|
|
333
|
+
select(InstanceModel).options(
|
|
334
|
+
joinedload(InstanceModel.volume_attachments).joinedload(
|
|
335
|
+
VolumeAttachmentModel.volume
|
|
336
|
+
)
|
|
337
|
+
)
|
|
334
338
|
)
|
|
335
339
|
instance = res.unique().scalar_one()
|
|
336
|
-
assert instance.
|
|
340
|
+
assert len(instance.volume_attachments) == 1
|
|
341
|
+
assert instance.volume_attachments[0].volume == volume_2
|
|
@@ -11,7 +11,7 @@ from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
11
11
|
|
|
12
12
|
from dstack._internal.core.models.backends.base import BackendType
|
|
13
13
|
from dstack._internal.core.models.users import GlobalRole, ProjectRole
|
|
14
|
-
from dstack._internal.server.models import VolumeModel
|
|
14
|
+
from dstack._internal.server.models import VolumeAttachmentModel, VolumeModel
|
|
15
15
|
from dstack._internal.server.services.projects import add_project_member
|
|
16
16
|
from dstack._internal.server.testing.common import (
|
|
17
17
|
create_instance,
|
|
@@ -76,6 +76,7 @@ class TestListVolumes:
|
|
|
76
76
|
"deleted": False,
|
|
77
77
|
"volume_id": None,
|
|
78
78
|
"provisioning_data": None,
|
|
79
|
+
"attachments": [],
|
|
79
80
|
"attachment_data": None,
|
|
80
81
|
},
|
|
81
82
|
{
|
|
@@ -91,6 +92,7 @@ class TestListVolumes:
|
|
|
91
92
|
"deleted": False,
|
|
92
93
|
"volume_id": None,
|
|
93
94
|
"provisioning_data": None,
|
|
95
|
+
"attachments": [],
|
|
94
96
|
"attachment_data": None,
|
|
95
97
|
},
|
|
96
98
|
]
|
|
@@ -117,6 +119,7 @@ class TestListVolumes:
|
|
|
117
119
|
"deleted": False,
|
|
118
120
|
"volume_id": None,
|
|
119
121
|
"provisioning_data": None,
|
|
122
|
+
"attachments": [],
|
|
120
123
|
"attachment_data": None,
|
|
121
124
|
},
|
|
122
125
|
]
|
|
@@ -170,6 +173,7 @@ class TestListVolumes:
|
|
|
170
173
|
"deleted": False,
|
|
171
174
|
"volume_id": None,
|
|
172
175
|
"provisioning_data": None,
|
|
176
|
+
"attachments": [],
|
|
173
177
|
"attachment_data": None,
|
|
174
178
|
},
|
|
175
179
|
]
|
|
@@ -217,6 +221,7 @@ class TestListProjectVolumes:
|
|
|
217
221
|
"deleted": False,
|
|
218
222
|
"volume_id": None,
|
|
219
223
|
"provisioning_data": None,
|
|
224
|
+
"attachments": [],
|
|
220
225
|
"attachment_data": None,
|
|
221
226
|
}
|
|
222
227
|
]
|
|
@@ -264,6 +269,7 @@ class TestGetVolume:
|
|
|
264
269
|
"deleted": False,
|
|
265
270
|
"volume_id": None,
|
|
266
271
|
"provisioning_data": None,
|
|
272
|
+
"attachments": [],
|
|
267
273
|
"attachment_data": None,
|
|
268
274
|
}
|
|
269
275
|
|
|
@@ -325,6 +331,7 @@ class TestCreateVolume:
|
|
|
325
331
|
"deleted": False,
|
|
326
332
|
"volume_id": None,
|
|
327
333
|
"provisioning_data": None,
|
|
334
|
+
"attachments": [],
|
|
328
335
|
"attachment_data": None,
|
|
329
336
|
}
|
|
330
337
|
res = await session.execute(select(VolumeModel))
|
|
@@ -391,7 +398,7 @@ class TestDeleteVolumes:
|
|
|
391
398
|
project=project,
|
|
392
399
|
pool=pool,
|
|
393
400
|
)
|
|
394
|
-
volume.
|
|
401
|
+
volume.attachments.append(VolumeAttachmentModel(instance=instance))
|
|
395
402
|
await session.commit()
|
|
396
403
|
response = await client.post(
|
|
397
404
|
f"/api/project/{project.name}/volumes/delete",
|