dstack 0.18.42__py3-none-any.whl → 0.18.44__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.
Files changed (115) hide show
  1. dstack/_internal/cli/commands/__init__.py +2 -1
  2. dstack/_internal/cli/commands/apply.py +4 -2
  3. dstack/_internal/cli/commands/attach.py +21 -1
  4. dstack/_internal/cli/commands/completion.py +20 -0
  5. dstack/_internal/cli/commands/delete.py +3 -1
  6. dstack/_internal/cli/commands/fleet.py +2 -1
  7. dstack/_internal/cli/commands/gateway.py +7 -2
  8. dstack/_internal/cli/commands/logs.py +3 -2
  9. dstack/_internal/cli/commands/stats.py +2 -1
  10. dstack/_internal/cli/commands/stop.py +2 -1
  11. dstack/_internal/cli/commands/volume.py +2 -1
  12. dstack/_internal/cli/main.py +6 -0
  13. dstack/_internal/cli/services/completion.py +86 -0
  14. dstack/_internal/cli/services/configurators/run.py +11 -17
  15. dstack/_internal/cli/utils/fleet.py +5 -1
  16. dstack/_internal/cli/utils/run.py +11 -0
  17. dstack/_internal/core/backends/aws/compute.py +23 -10
  18. dstack/_internal/core/backends/aws/resources.py +3 -3
  19. dstack/_internal/core/backends/azure/compute.py +15 -9
  20. dstack/_internal/core/backends/azure/resources.py +2 -0
  21. dstack/_internal/core/backends/base/compute.py +102 -2
  22. dstack/_internal/core/backends/base/offers.py +7 -1
  23. dstack/_internal/core/backends/cudo/compute.py +8 -4
  24. dstack/_internal/core/backends/datacrunch/compute.py +10 -4
  25. dstack/_internal/core/backends/gcp/auth.py +19 -13
  26. dstack/_internal/core/backends/gcp/compute.py +26 -20
  27. dstack/_internal/core/backends/gcp/resources.py +3 -10
  28. dstack/_internal/core/backends/kubernetes/compute.py +4 -3
  29. dstack/_internal/core/backends/lambdalabs/compute.py +9 -3
  30. dstack/_internal/core/backends/nebius/compute.py +2 -2
  31. dstack/_internal/core/backends/oci/compute.py +10 -4
  32. dstack/_internal/core/backends/runpod/compute.py +32 -7
  33. dstack/_internal/core/backends/runpod/config.py +8 -0
  34. dstack/_internal/core/backends/tensordock/compute.py +14 -3
  35. dstack/_internal/core/backends/vastai/compute.py +12 -2
  36. dstack/_internal/core/backends/vultr/api_client.py +3 -3
  37. dstack/_internal/core/backends/vultr/compute.py +9 -3
  38. dstack/_internal/core/models/backends/aws.py +2 -0
  39. dstack/_internal/core/models/backends/base.py +1 -0
  40. dstack/_internal/core/models/backends/runpod.py +2 -0
  41. dstack/_internal/core/models/configurations.py +2 -2
  42. dstack/_internal/core/models/profiles.py +46 -1
  43. dstack/_internal/core/models/runs.py +4 -0
  44. dstack/_internal/core/services/__init__.py +5 -1
  45. dstack/_internal/core/services/configs/__init__.py +3 -0
  46. dstack/_internal/server/app.py +11 -1
  47. dstack/_internal/server/background/__init__.py +10 -0
  48. dstack/_internal/server/background/tasks/common.py +22 -0
  49. dstack/_internal/server/background/tasks/process_instances.py +11 -18
  50. dstack/_internal/server/background/tasks/process_placement_groups.py +1 -0
  51. dstack/_internal/server/background/tasks/process_prometheus_metrics.py +135 -0
  52. dstack/_internal/server/background/tasks/process_running_jobs.py +74 -34
  53. dstack/_internal/server/background/tasks/process_runs.py +1 -0
  54. dstack/_internal/server/background/tasks/process_submitted_jobs.py +4 -1
  55. dstack/_internal/server/background/tasks/process_terminating_jobs.py +1 -7
  56. dstack/_internal/server/migrations/versions/60e444118b6d_add_jobprometheusmetrics.py +40 -0
  57. dstack/_internal/server/migrations/versions/98d1b92988bc_add_jobterminationreason_terminated_due_.py +140 -0
  58. dstack/_internal/server/models.py +11 -0
  59. dstack/_internal/server/routers/logs.py +3 -0
  60. dstack/_internal/server/routers/metrics.py +21 -2
  61. dstack/_internal/server/routers/prometheus.py +36 -0
  62. dstack/_internal/server/security/permissions.py +1 -1
  63. dstack/_internal/server/services/backends/configurators/aws.py +31 -1
  64. dstack/_internal/server/services/backends/configurators/gcp.py +8 -15
  65. dstack/_internal/server/services/backends/configurators/runpod.py +3 -33
  66. dstack/_internal/server/services/config.py +24 -4
  67. dstack/_internal/server/services/fleets.py +1 -0
  68. dstack/_internal/server/services/gateways/__init__.py +1 -0
  69. dstack/_internal/server/services/jobs/__init__.py +12 -9
  70. dstack/_internal/server/services/jobs/configurators/base.py +9 -1
  71. dstack/_internal/server/services/jobs/configurators/dev.py +1 -3
  72. dstack/_internal/server/services/jobs/configurators/task.py +1 -3
  73. dstack/_internal/server/services/logs/__init__.py +78 -0
  74. dstack/_internal/server/services/{logs.py → logs/aws.py} +12 -207
  75. dstack/_internal/server/services/logs/base.py +47 -0
  76. dstack/_internal/server/services/logs/filelog.py +110 -0
  77. dstack/_internal/server/services/logs/gcp.py +165 -0
  78. dstack/_internal/server/services/metrics.py +103 -70
  79. dstack/_internal/server/services/pools.py +16 -17
  80. dstack/_internal/server/services/prometheus.py +87 -0
  81. dstack/_internal/server/services/proxy/routers/service_proxy.py +14 -7
  82. dstack/_internal/server/services/runner/client.py +14 -3
  83. dstack/_internal/server/services/runs.py +43 -15
  84. dstack/_internal/server/services/volumes.py +1 -0
  85. dstack/_internal/server/settings.py +6 -0
  86. dstack/_internal/server/statics/index.html +1 -1
  87. dstack/_internal/server/statics/{main-2ac66bfcbd2e39830b88.js → main-4eb116b97819badd1e2c.js} +131 -78
  88. dstack/_internal/server/statics/{main-2ac66bfcbd2e39830b88.js.map → main-4eb116b97819badd1e2c.js.map} +1 -1
  89. dstack/_internal/server/statics/{main-ad5150a441de98cd8987.css → main-da9f8c06a69c20dac23e.css} +1 -1
  90. dstack/_internal/server/statics/static/media/entraID.d65d1f3e9486a8e56d24fc07b3230885.svg +9 -0
  91. dstack/_internal/server/testing/common.py +50 -8
  92. dstack/api/_public/runs.py +4 -1
  93. dstack/api/server/_fleets.py +2 -0
  94. dstack/api/server/_runs.py +4 -0
  95. dstack/api/utils.py +3 -0
  96. dstack/version.py +2 -2
  97. {dstack-0.18.42.dist-info → dstack-0.18.44.dist-info}/METADATA +13 -3
  98. {dstack-0.18.42.dist-info → dstack-0.18.44.dist-info}/RECORD +115 -97
  99. tests/_internal/core/backends/base/__init__.py +0 -0
  100. tests/_internal/core/backends/base/test_compute.py +56 -0
  101. tests/_internal/server/background/tasks/test_process_prometheus_metrics.py +189 -0
  102. tests/_internal/server/background/tasks/test_process_running_jobs.py +126 -1
  103. tests/_internal/server/conftest.py +4 -5
  104. tests/_internal/server/routers/test_backends.py +1 -0
  105. tests/_internal/server/routers/test_fleets.py +2 -0
  106. tests/_internal/server/routers/test_logs.py +1 -1
  107. tests/_internal/server/routers/test_metrics.py +15 -0
  108. tests/_internal/server/routers/test_prometheus.py +244 -0
  109. tests/_internal/server/routers/test_runs.py +81 -58
  110. tests/_internal/server/services/test_logs.py +3 -3
  111. tests/_internal/server/services/test_metrics.py +163 -0
  112. {dstack-0.18.42.dist-info → dstack-0.18.44.dist-info}/LICENSE.md +0 -0
  113. {dstack-0.18.42.dist-info → dstack-0.18.44.dist-info}/WHEEL +0 -0
  114. {dstack-0.18.42.dist-info → dstack-0.18.44.dist-info}/entry_points.txt +0 -0
  115. {dstack-0.18.42.dist-info → dstack-0.18.44.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,9 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg id="uuid-f8d4d392-7c12-4bd9-baff-66fbf7814b91" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 18 18">
3
+ <path d="m3.802,14.032c.388.242,1.033.511,1.715.511.621,0,1.198-.18,1.676-.487,0,0,.001,0,.002-.001l1.805-1.128v4.073c-.286,0-.574-.078-.824-.234l-4.374-2.734Z" fill="#225086"/>
4
+ <path d="m7.853,1.507L.353,9.967c-.579.654-.428,1.642.323,2.111,0,0,2.776,1.735,3.126,1.954.388.242,1.033.511,1.715.511.621,0,1.198-.18,1.676-.487,0,0,.001,0,.002-.001l1.805-1.128-4.364-2.728,4.365-4.924V1s0,0,0,0c-.424,0-.847.169-1.147.507Z" fill="#6df"/>
5
+ <polygon points="4.636 10.199 4.688 10.231 9 12.927 9.001 12.927 9.001 12.927 9.001 5.276 9 5.275 4.636 10.199" fill="#cbf8ff"/>
6
+ <path d="m17.324,12.078c.751-.469.902-1.457.323-2.111l-4.921-5.551c-.397-.185-.842-.291-1.313-.291-.925,0-1.752.399-2.302,1.026l-.109.123h0s4.364,4.924,4.364,4.924h0s0,0,0,0l-4.365,2.728v4.073c.287,0,.573-.078.823-.234l7.5-4.688Z" fill="#074793"/>
7
+ <path d="m9.001,1v4.275s.109-.123.109-.123c.55-.627,1.377-1.026,2.302-1.026.472,0,.916.107,1.313.291l-2.579-2.909c-.299-.338-.723-.507-1.146-.507Z" fill="#0294e4"/>
8
+ <polygon points="13.365 10.199 13.365 10.199 13.365 10.199 9.001 5.276 9.001 12.926 13.365 10.199" fill="#96bcc2"/>
9
+ </svg>
@@ -16,7 +16,7 @@ from dstack._internal.core.models.configurations import (
16
16
  )
17
17
  from dstack._internal.core.models.envs import Env
18
18
  from dstack._internal.core.models.fleets import FleetConfiguration, FleetSpec, FleetStatus
19
- from dstack._internal.core.models.gateways import GatewayStatus
19
+ from dstack._internal.core.models.gateways import GatewayComputeConfiguration, GatewayStatus
20
20
  from dstack._internal.core.models.instances import (
21
21
  Disk,
22
22
  Gpu,
@@ -69,6 +69,7 @@ from dstack._internal.server.models import (
69
69
  InstanceModel,
70
70
  JobMetricsPoint,
71
71
  JobModel,
72
+ JobPrometheusMetrics,
72
73
  PlacementGroupModel,
73
74
  PoolModel,
74
75
  ProjectModel,
@@ -420,6 +421,24 @@ async def create_gateway_compute(
420
421
  return gateway_compute
421
422
 
422
423
 
424
+ def get_gateway_compute_configuration(
425
+ project_name: str = "test-project",
426
+ instance_name: str = "test-instance",
427
+ backend: BackendType = BackendType.AWS,
428
+ region: str = "us",
429
+ public_ip: bool = True,
430
+ ) -> GatewayComputeConfiguration:
431
+ return GatewayComputeConfiguration(
432
+ project_name=project_name,
433
+ instance_name=instance_name,
434
+ backend=backend,
435
+ region=region,
436
+ public_ip=public_ip,
437
+ ssh_key_pub="",
438
+ certificate=None,
439
+ )
440
+
441
+
423
442
  async def create_pool(
424
443
  session: AsyncSession,
425
444
  project: ProjectModel,
@@ -533,13 +552,7 @@ async def create_instance(
533
552
  requirements = Requirements(resources=ResourcesSpec(cpu=1))
534
553
 
535
554
  if instance_configuration is None:
536
- instance_configuration = InstanceConfiguration(
537
- project_name="test_proj",
538
- instance_name="test_instance_name",
539
- instance_id="test instance id",
540
- ssh_keys=[],
541
- user="test_user",
542
- )
555
+ instance_configuration = get_instance_configuration()
543
556
 
544
557
  if volumes is None:
545
558
  volumes = []
@@ -581,6 +594,19 @@ async def create_instance(
581
594
  return im
582
595
 
583
596
 
597
+ def get_instance_configuration(
598
+ project_name: str = "test-project",
599
+ instance_name: str = "test-instance",
600
+ user: str = "dstack-user",
601
+ ) -> InstanceConfiguration:
602
+ return InstanceConfiguration(
603
+ project_name=project_name,
604
+ instance_name=instance_name,
605
+ user=user,
606
+ ssh_keys=[],
607
+ )
608
+
609
+
584
610
  def get_instance_offer_with_availability(
585
611
  backend: BackendType = BackendType.AWS,
586
612
  region: str = "eu-west",
@@ -833,6 +859,22 @@ async def create_job_metrics_point(
833
859
  return jmp
834
860
 
835
861
 
862
+ async def create_job_prometheus_metrics(
863
+ session: AsyncSession,
864
+ job: JobModel,
865
+ collected_at: datetime = datetime(2023, 1, 2, 3, 4, tzinfo=timezone.utc),
866
+ text: str = "# Prometheus metrics\n",
867
+ ):
868
+ metrics = JobPrometheusMetrics(
869
+ job_id=job.id,
870
+ collected_at=collected_at,
871
+ text=text,
872
+ )
873
+ session.add(metrics)
874
+ await session.commit()
875
+ return metrics
876
+
877
+
836
878
  def get_private_key_string() -> str:
837
879
  return """
838
880
  -----BEGIN RSA PRIVATE KEY-----
@@ -25,6 +25,7 @@ from dstack._internal.core.models.profiles import (
25
25
  ProfileRetryPolicy,
26
26
  SpotPolicy,
27
27
  TerminationPolicy,
28
+ UtilizationPolicy,
28
29
  )
29
30
  from dstack._internal.core.models.repos.base import Repo
30
31
  from dstack._internal.core.models.resources import ResourcesSpec
@@ -215,7 +216,7 @@ class Run(ABC):
215
216
  start_time=next_start_time,
216
217
  end_time=None,
217
218
  descending=False,
218
- limit=100,
219
+ limit=1000,
219
220
  diagnose=diagnose,
220
221
  ),
221
222
  )
@@ -485,6 +486,7 @@ class RunCollection:
485
486
  resources: Optional[ResourcesSpec] = None,
486
487
  spot_policy: Optional[SpotPolicy] = None,
487
488
  retry_policy: Optional[ProfileRetryPolicy] = None,
489
+ utilization_policy: Optional[UtilizationPolicy] = None,
488
490
  max_duration: Optional[Union[int, str]] = None,
489
491
  max_price: Optional[float] = None,
490
492
  working_dir: Optional[str] = None,
@@ -535,6 +537,7 @@ class RunCollection:
535
537
  spot_policy=spot_policy,
536
538
  retry=None,
537
539
  retry_policy=retry_policy,
540
+ utilization_policy=utilization_policy,
538
541
  max_duration=max_duration,
539
542
  stop_duration=stop_duration,
540
543
  max_price=max_price,
@@ -104,6 +104,8 @@ def _get_fleet_spec_excludes(fleet_spec: FleetSpec) -> Optional[_ExcludeDict]:
104
104
  profile_excludes.add("availability_zones")
105
105
  if fleet_spec.configuration.blocks == 1:
106
106
  configuration_excludes["blocks"] = True
107
+ if fleet_spec.profile is not None and fleet_spec.profile.utilization_policy is None:
108
+ profile_excludes.add("utilization_policy")
107
109
 
108
110
  if ssh_hosts_excludes:
109
111
  ssh_config_excludes["hosts"] = {"__all__": ssh_hosts_excludes}
@@ -185,6 +185,10 @@ def _get_run_spec_excludes(run_spec: RunSpec) -> Optional[dict]:
185
185
  and configuration.inactivity_duration is None
186
186
  ):
187
187
  configuration_excludes["inactivity_duration"] = True
188
+ if configuration.utilization_policy is None:
189
+ configuration_excludes["utilization_policy"] = True
190
+ if profile is not None and profile.utilization_policy is None:
191
+ profile_excludes.add("utilization_policy")
188
192
 
189
193
  if configuration_excludes:
190
194
  spec_excludes["configuration"] = configuration_excludes
dstack/api/utils.py CHANGED
@@ -2,6 +2,7 @@ from pathlib import Path
2
2
  from typing import Optional, Tuple
3
3
 
4
4
  import yaml
5
+ from pydantic import ValidationError
5
6
 
6
7
  from dstack._internal.core.errors import ConfigurationError
7
8
  from dstack._internal.core.models.configurations import AnyRunConfiguration
@@ -96,6 +97,8 @@ def _load_profile_from_path(profiles_path: Path, profile_name: Optional[str]) ->
96
97
  config = ProfilesConfig.parse_obj(yaml.safe_load(f))
97
98
  except FileNotFoundError:
98
99
  return None
100
+ except ValidationError as e:
101
+ raise ConfigurationError(e)
99
102
 
100
103
  if profile_name is None:
101
104
  return config.default()
dstack/version.py CHANGED
@@ -1,3 +1,3 @@
1
- __version__ = "0.18.42"
1
+ __version__ = "0.18.44"
2
2
  __is_release__ = True
3
- base_image = "0.6"
3
+ base_image = "0.7"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dstack
3
- Version: 0.18.42
3
+ Version: 0.18.44
4
4
  Summary: dstack is an open-source orchestration engine for running AI workloads on any cloud or on-premises.
5
5
  Home-page: https://dstack.ai
6
6
  Author: Andrey Cheptsov
@@ -37,7 +37,8 @@ Requires-Dist: websocket-client
37
37
  Requires-Dist: python-multipart>=0.0.16
38
38
  Requires-Dist: filelock
39
39
  Requires-Dist: psutil
40
- Requires-Dist: gpuhunt<0.1.0,>=0.0.19
40
+ Requires-Dist: gpuhunt<0.2.0,>=0.1.0
41
+ Requires-Dist: argcomplete>=3.5.0
41
42
  Provides-Extra: all
42
43
  Requires-Dist: fastapi; extra == "all"
43
44
  Requires-Dist: starlette>=0.26.0; extra == "all"
@@ -59,6 +60,7 @@ Requires-Dist: alembic-postgresql-enum; extra == "all"
59
60
  Requires-Dist: asyncpg; extra == "all"
60
61
  Requires-Dist: cachetools; extra == "all"
61
62
  Requires-Dist: python-json-logger>=3.1.0; extra == "all"
63
+ Requires-Dist: prometheus-client; extra == "all"
62
64
  Requires-Dist: grpcio>=1.50; extra == "all"
63
65
  Requires-Dist: boto3; extra == "all"
64
66
  Requires-Dist: botocore; extra == "all"
@@ -99,6 +101,7 @@ Requires-Dist: alembic-postgresql-enum; extra == "aws"
99
101
  Requires-Dist: asyncpg; extra == "aws"
100
102
  Requires-Dist: cachetools; extra == "aws"
101
103
  Requires-Dist: python-json-logger>=3.1.0; extra == "aws"
104
+ Requires-Dist: prometheus-client; extra == "aws"
102
105
  Requires-Dist: grpcio>=1.50; extra == "aws"
103
106
  Requires-Dist: boto3; extra == "aws"
104
107
  Requires-Dist: botocore; extra == "aws"
@@ -123,6 +126,7 @@ Requires-Dist: alembic-postgresql-enum; extra == "azure"
123
126
  Requires-Dist: asyncpg; extra == "azure"
124
127
  Requires-Dist: cachetools; extra == "azure"
125
128
  Requires-Dist: python-json-logger>=3.1.0; extra == "azure"
129
+ Requires-Dist: prometheus-client; extra == "azure"
126
130
  Requires-Dist: grpcio>=1.50; extra == "azure"
127
131
  Requires-Dist: azure-identity>=1.12.0; extra == "azure"
128
132
  Requires-Dist: azure-mgmt-subscription>=3.1.1; extra == "azure"
@@ -151,6 +155,7 @@ Requires-Dist: alembic-postgresql-enum; extra == "datacrunch"
151
155
  Requires-Dist: asyncpg; extra == "datacrunch"
152
156
  Requires-Dist: cachetools; extra == "datacrunch"
153
157
  Requires-Dist: python-json-logger>=3.1.0; extra == "datacrunch"
158
+ Requires-Dist: prometheus-client; extra == "datacrunch"
154
159
  Requires-Dist: grpcio>=1.50; extra == "datacrunch"
155
160
  Requires-Dist: datacrunch; extra == "datacrunch"
156
161
  Provides-Extra: gateway
@@ -182,6 +187,7 @@ Requires-Dist: alembic-postgresql-enum; extra == "gcp"
182
187
  Requires-Dist: asyncpg; extra == "gcp"
183
188
  Requires-Dist: cachetools; extra == "gcp"
184
189
  Requires-Dist: python-json-logger>=3.1.0; extra == "gcp"
190
+ Requires-Dist: prometheus-client; extra == "gcp"
185
191
  Requires-Dist: grpcio>=1.50; extra == "gcp"
186
192
  Requires-Dist: google-auth>=2.3.0; extra == "gcp"
187
193
  Requires-Dist: google-cloud-storage>=2.0.0; extra == "gcp"
@@ -211,6 +217,7 @@ Requires-Dist: alembic-postgresql-enum; extra == "kubernetes"
211
217
  Requires-Dist: asyncpg; extra == "kubernetes"
212
218
  Requires-Dist: cachetools; extra == "kubernetes"
213
219
  Requires-Dist: python-json-logger>=3.1.0; extra == "kubernetes"
220
+ Requires-Dist: prometheus-client; extra == "kubernetes"
214
221
  Requires-Dist: grpcio>=1.50; extra == "kubernetes"
215
222
  Requires-Dist: kubernetes; extra == "kubernetes"
216
223
  Provides-Extra: lambda
@@ -234,6 +241,7 @@ Requires-Dist: alembic-postgresql-enum; extra == "lambda"
234
241
  Requires-Dist: asyncpg; extra == "lambda"
235
242
  Requires-Dist: cachetools; extra == "lambda"
236
243
  Requires-Dist: python-json-logger>=3.1.0; extra == "lambda"
244
+ Requires-Dist: prometheus-client; extra == "lambda"
237
245
  Requires-Dist: grpcio>=1.50; extra == "lambda"
238
246
  Requires-Dist: boto3; extra == "lambda"
239
247
  Requires-Dist: botocore; extra == "lambda"
@@ -258,6 +266,7 @@ Requires-Dist: alembic-postgresql-enum; extra == "oci"
258
266
  Requires-Dist: asyncpg; extra == "oci"
259
267
  Requires-Dist: cachetools; extra == "oci"
260
268
  Requires-Dist: python-json-logger>=3.1.0; extra == "oci"
269
+ Requires-Dist: prometheus-client; extra == "oci"
261
270
  Requires-Dist: grpcio>=1.50; extra == "oci"
262
271
  Requires-Dist: oci; extra == "oci"
263
272
  Provides-Extra: server
@@ -281,6 +290,7 @@ Requires-Dist: alembic-postgresql-enum; extra == "server"
281
290
  Requires-Dist: asyncpg; extra == "server"
282
291
  Requires-Dist: cachetools; extra == "server"
283
292
  Requires-Dist: python-json-logger>=3.1.0; extra == "server"
293
+ Requires-Dist: prometheus-client; extra == "server"
284
294
  Requires-Dist: grpcio>=1.50; extra == "server"
285
295
 
286
296
  <div style="text-align: center;">
@@ -307,9 +317,9 @@ for AI workloads both in the cloud and on-prem, speeding up the development, tra
307
317
 
308
318
  ## Major news ✨
309
319
 
320
+ - [2025/02] [dstack 0.18.41: GPU blocks, Proxy jump, inactivity duration, and more](https://github.com/dstackai/dstack/releases/tag/0.18.41)
310
321
  - [2025/01] [dstack 0.18.38: Intel Gaudi](https://github.com/dstackai/dstack/releases/tag/0.18.38)
311
322
  - [2025/01] [dstack 0.18.35: Vultr](https://github.com/dstackai/dstack/releases/tag/0.18.35)
312
- - [2024/12] [dstack 0.18.32: TPU v6e](https://github.com/dstackai/dstack/releases/tag/0.18.32)
313
323
  - [2024/12] [dstack 0.18.30: AWS Capacity Reservations and Capacity Blocks](https://github.com/dstackai/dstack/releases/tag/0.18.30)
314
324
  - [2024/10] [dstack 0.18.21: Instance volumes](https://github.com/dstackai/dstack/releases/tag/0.18.21)
315
325
  - [2024/10] [dstack 0.18.18: Hardware metrics monitoring](https://github.com/dstackai/dstack/releases/tag/0.18.18)