dstack 0.19.33__py3-none-any.whl → 0.19.34__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.

Files changed (28) hide show
  1. dstack/_internal/core/backends/base/offers.py +3 -1
  2. dstack/_internal/core/backends/gcp/compute.py +24 -9
  3. dstack/_internal/core/backends/gcp/models.py +4 -1
  4. dstack/_internal/core/backends/runpod/compute.py +4 -1
  5. dstack/_internal/core/compatibility/runs.py +25 -4
  6. dstack/_internal/core/models/instances.py +2 -1
  7. dstack/_internal/core/models/runs.py +1 -0
  8. dstack/_internal/core/services/ssh/key_manager.py +56 -0
  9. dstack/_internal/server/models.py +3 -0
  10. dstack/_internal/server/routers/metrics.py +6 -2
  11. dstack/_internal/server/routers/users.py +7 -0
  12. dstack/_internal/server/services/jobs/__init__.py +18 -9
  13. dstack/_internal/server/services/offers.py +1 -0
  14. dstack/_internal/server/services/runs.py +4 -0
  15. dstack/_internal/server/services/users.py +3 -3
  16. dstack/_internal/server/statics/index.html +1 -1
  17. dstack/_internal/server/statics/{main-97c7e184573ca23f9fe4.js → main-e79754c136f1d8e4e7e6.js} +11 -11
  18. dstack/_internal/server/statics/{main-97c7e184573ca23f9fe4.js.map → main-e79754c136f1d8e4e7e6.js.map} +1 -1
  19. dstack/_internal/server/testing/common.py +4 -0
  20. dstack/api/_public/__init__.py +2 -2
  21. dstack/api/_public/runs.py +36 -39
  22. dstack/api/server/__init__.py +4 -0
  23. dstack/version.py +1 -1
  24. {dstack-0.19.33.dist-info → dstack-0.19.34.dist-info}/METADATA +2 -2
  25. {dstack-0.19.33.dist-info → dstack-0.19.34.dist-info}/RECORD +28 -27
  26. {dstack-0.19.33.dist-info → dstack-0.19.34.dist-info}/WHEEL +0 -0
  27. {dstack-0.19.33.dist-info → dstack-0.19.34.dist-info}/entry_points.txt +0 -0
  28. {dstack-0.19.33.dist-info → dstack-0.19.34.dist-info}/licenses/LICENSE.md +0 -0
@@ -126,6 +126,8 @@ async def create_user(
126
126
  global_role: GlobalRole = GlobalRole.ADMIN,
127
127
  token: Optional[str] = None,
128
128
  email: Optional[str] = None,
129
+ ssh_public_key: Optional[str] = None,
130
+ ssh_private_key: Optional[str] = None,
129
131
  active: bool = True,
130
132
  ) -> UserModel:
131
133
  if token is None:
@@ -137,6 +139,8 @@ async def create_user(
137
139
  token=DecryptedString(plaintext=token),
138
140
  token_hash=get_token_hash(token),
139
141
  email=email,
142
+ ssh_public_key=ssh_public_key,
143
+ ssh_private_key=ssh_private_key,
140
144
  active=active,
141
145
  )
142
146
  session.add(user)
@@ -6,7 +6,7 @@ from dstack._internal.utils.logging import get_logger
6
6
  from dstack._internal.utils.path import PathLike as PathLike
7
7
  from dstack.api._public.backends import BackendCollection
8
8
  from dstack.api._public.repos import RepoCollection
9
- from dstack.api._public.runs import RunCollection, warn
9
+ from dstack.api._public.runs import RunCollection
10
10
  from dstack.api.server import APIClient
11
11
 
12
12
  logger = get_logger(__name__)
@@ -42,7 +42,7 @@ class Client:
42
42
  self._backends = BackendCollection(api_client, project_name)
43
43
  self._runs = RunCollection(api_client, project_name, self)
44
44
  if ssh_identity_file is not None:
45
- warn(
45
+ logger.warning(
46
46
  "[code]ssh_identity_file[/code] in [code]Client[/code] is deprecated and ignored; will be removed"
47
47
  " since 0.19.40"
48
48
  )
@@ -1,6 +1,4 @@
1
1
  import base64
2
- import hashlib
3
- import os
4
2
  import queue
5
3
  import tempfile
6
4
  import threading
@@ -17,7 +15,6 @@ from urllib.parse import urlparse
17
15
  from websocket import WebSocketApp
18
16
 
19
17
  import dstack.api as api
20
- from dstack._internal.cli.utils.common import warn
21
18
  from dstack._internal.core.consts import DSTACK_RUNNER_HTTP_PORT, DSTACK_RUNNER_SSH_PORT
22
19
  from dstack._internal.core.errors import ClientError, ConfigurationError, ResourceNotExistsError
23
20
  from dstack._internal.core.models.backends.base import BackendType
@@ -48,10 +45,10 @@ from dstack._internal.core.models.runs import (
48
45
  get_service_port,
49
46
  )
50
47
  from dstack._internal.core.models.runs import Run as RunModel
51
- from dstack._internal.core.models.users import UserWithCreds
52
48
  from dstack._internal.core.services.configs import ConfigManager
53
49
  from dstack._internal.core.services.logs import URLReplacer
54
50
  from dstack._internal.core.services.ssh.attach import SSHAttach
51
+ from dstack._internal.core.services.ssh.key_manager import UserSSHKeyManager
55
52
  from dstack._internal.core.services.ssh.ports import PortsLock
56
53
  from dstack._internal.server.schemas.logs import PollLogsRequest
57
54
  from dstack._internal.utils.common import get_or_error, make_proxy_url
@@ -88,7 +85,7 @@ class Run(ABC):
88
85
  self._ports_lock: Optional[PortsLock] = ports_lock
89
86
  self._ssh_attach: Optional[SSHAttach] = None
90
87
  if ssh_identity_file is not None:
91
- warn(
88
+ logger.warning(
92
89
  "[code]ssh_identity_file[/code] in [code]Run[/code] is deprecated and ignored; will be removed"
93
90
  " since 0.19.40"
94
91
  )
@@ -281,31 +278,20 @@ class Run(ABC):
281
278
  dstack.api.PortUsedError: If ports are in use or the run is attached by another process.
282
279
  """
283
280
  if not ssh_identity_file:
284
- user = self._api_client.users.get_my_user()
285
- run_ssh_key_pub = self._run.run_spec.ssh_key_pub
286
281
  config_manager = ConfigManager()
287
- if isinstance(user, UserWithCreds) and user.ssh_public_key == run_ssh_key_pub:
288
- token_hash = hashlib.sha1(user.creds.token.encode()).hexdigest()[:8]
289
- config_manager.dstack_ssh_dir.mkdir(parents=True, exist_ok=True)
290
- ssh_identity_file = config_manager.dstack_ssh_dir / token_hash
291
-
292
- def key_opener(path, flags):
293
- return os.open(path, flags, 0o600)
294
-
295
- with open(ssh_identity_file, "wb", opener=key_opener) as f:
296
- assert user.ssh_private_key
297
- f.write(user.ssh_private_key.encode())
282
+ key_manager = UserSSHKeyManager(self._api_client, config_manager.dstack_ssh_dir)
283
+ if (
284
+ user_key := key_manager.get_user_key()
285
+ ) and user_key.public_key == self._run.run_spec.ssh_key_pub:
286
+ ssh_identity_file = user_key.private_key_path
298
287
  else:
299
288
  if config_manager.dstack_key_path.exists():
300
289
  # TODO: Remove since 0.19.40
301
- warn(
302
- f"Using legacy [code]{config_manager.dstack_key_path}[/code]."
303
- " Future versions will use the user SSH key from the server.",
304
- )
290
+ logger.debug(f"Using legacy [code]{config_manager.dstack_key_path}[/code].")
305
291
  ssh_identity_file = config_manager.dstack_key_path
306
292
  else:
307
293
  raise ConfigurationError(
308
- f"User SSH key doen't match; default SSH key ({config_manager.dstack_key_path}) doesn't exist"
294
+ f"User SSH key doesn't match; default SSH key ({config_manager.dstack_key_path}) doesn't exist"
309
295
  )
310
296
  ssh_identity_file = str(ssh_identity_file)
311
297
 
@@ -504,15 +490,19 @@ class RunCollection:
504
490
  ssh_key_pub = Path(ssh_identity_file).with_suffix(".pub").read_text()
505
491
  else:
506
492
  config_manager = ConfigManager()
507
- if not config_manager.dstack_key_path.exists():
508
- generate_rsa_key_pair(private_key_path=config_manager.dstack_key_path)
509
- warn(
510
- f"Using legacy [code]{config_manager.dstack_key_path.with_suffix('.pub')}[/code]."
511
- " Future versions will use the user SSH key from the server.",
512
- )
513
- ssh_key_pub = config_manager.dstack_key_path.with_suffix(".pub").read_text()
514
- # TODO: Uncomment after 0.19.40
515
- # ssh_key_pub = None
493
+ key_manager = UserSSHKeyManager(self._api_client, config_manager.dstack_ssh_dir)
494
+ if key_manager.get_user_key():
495
+ ssh_key_pub = None # using the server-managed user key
496
+ else:
497
+ if not config_manager.dstack_key_path.exists():
498
+ generate_rsa_key_pair(private_key_path=config_manager.dstack_key_path)
499
+ logger.warning(
500
+ f"Using legacy [code]{config_manager.dstack_key_path.with_suffix('.pub')}[/code]."
501
+ " You will only be able to attach to the run from this client."
502
+ " Update the [code]dstack[/] server to [code]0.19.34[/]+ to switch to user keys"
503
+ " automatically replicated to all clients.",
504
+ )
505
+ ssh_key_pub = config_manager.dstack_key_path.with_suffix(".pub").read_text()
516
506
  run_spec = RunSpec(
517
507
  run_name=configuration.name,
518
508
  repo_id=repo.repo_id,
@@ -760,12 +750,19 @@ class RunCollection:
760
750
  idle_duration=idle_duration, # type: ignore[assignment]
761
751
  )
762
752
  config_manager = ConfigManager()
763
- if not config_manager.dstack_key_path.exists():
764
- generate_rsa_key_pair(private_key_path=config_manager.dstack_key_path)
765
- warn(
766
- f"Using legacy [code]{config_manager.dstack_key_path.with_suffix('.pub')}[/code]."
767
- " Future versions will use the user SSH key from the server.",
768
- )
753
+ key_manager = UserSSHKeyManager(self._api_client, config_manager.dstack_ssh_dir)
754
+ if key_manager.get_user_key():
755
+ ssh_key_pub = None # using the server-managed user key
756
+ else:
757
+ if not config_manager.dstack_key_path.exists():
758
+ generate_rsa_key_pair(private_key_path=config_manager.dstack_key_path)
759
+ logger.warning(
760
+ f"Using legacy [code]{config_manager.dstack_key_path.with_suffix('.pub')}[/code]."
761
+ " You will only be able to attach to the run from this client."
762
+ " Update the [code]dstack[/] server to [code]0.19.34[/]+ to switch to user keys"
763
+ " automatically replicated to all clients.",
764
+ )
765
+ ssh_key_pub = config_manager.dstack_key_path.with_suffix(".pub").read_text()
769
766
  run_spec = RunSpec(
770
767
  run_name=run_name,
771
768
  repo_id=repo.repo_id,
@@ -775,7 +772,7 @@ class RunCollection:
775
772
  configuration_path=configuration_path,
776
773
  configuration=configuration,
777
774
  profile=profile,
778
- ssh_key_pub=config_manager.dstack_key_path.with_suffix(".pub").read_text(),
775
+ ssh_key_pub=ssh_key_pub,
779
776
  )
780
777
  logger.debug("Getting run plan")
781
778
  run_plan = self._api_client.runs.get_plan(self._project, run_spec)
@@ -1,3 +1,4 @@
1
+ import hashlib
1
2
  import os
2
3
  import pprint
3
4
  import time
@@ -121,6 +122,9 @@ class APIClient:
121
122
  def files(self) -> FilesAPIClient:
122
123
  return FilesAPIClient(self._request, self._logger)
123
124
 
125
+ def get_token_hash(self) -> str:
126
+ return hashlib.sha1(self._token.encode()).hexdigest()[:8]
127
+
124
128
  def _request(
125
129
  self,
126
130
  path: str,
dstack/version.py CHANGED
@@ -1,4 +1,4 @@
1
- __version__ = "0.19.33"
1
+ __version__ = "0.19.34"
2
2
  __is_release__ = True
3
3
  base_image = "0.11"
4
4
  base_image_ubuntu_version = "22.04"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dstack
3
- Version: 0.19.33
3
+ Version: 0.19.34
4
4
  Summary: dstack is an open-source orchestration engine for running AI workloads on any cloud or on-premises.
5
5
  Project-URL: Homepage, https://dstack.ai
6
6
  Project-URL: Source, https://github.com/dstackai/dstack
@@ -22,7 +22,7 @@ Requires-Dist: cryptography
22
22
  Requires-Dist: cursor
23
23
  Requires-Dist: filelock
24
24
  Requires-Dist: gitpython
25
- Requires-Dist: gpuhunt==0.1.10
25
+ Requires-Dist: gpuhunt==0.1.11
26
26
  Requires-Dist: ignore-python>=0.2.0
27
27
  Requires-Dist: jsonschema
28
28
  Requires-Dist: orjson
@@ -1,5 +1,5 @@
1
1
  dstack/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- dstack/version.py,sha256=_FEUL4dv2EnNUXCWAEH2UsClkAJ5_z4QOZGhqRl7P-Q,102
2
+ dstack/version.py,sha256=cU-T_RUTMX-To2Q6GW3Ek5yh2PStRLSst-4zkMlB0Do,102
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=FYtd7tRk17Oc62Kl_3O8NuT5JHb8TKhLThl1TsfjjVs,1390
@@ -76,7 +76,7 @@ dstack/_internal/core/backends/base/backend.py,sha256=hdFMHED1RMV9GVfLSU0yGhGE-c
76
76
  dstack/_internal/core/backends/base/compute.py,sha256=MEglNP0H9iLi0a88ElRUxVcs1-qtpGEuWkxnrBp4KoA,36018
77
77
  dstack/_internal/core/backends/base/configurator.py,sha256=TKG5iJlOXxVT2agE_ruMW8JGt2dtwXY7ghmJN8bEWlw,4299
78
78
  dstack/_internal/core/backends/base/models.py,sha256=Ij0osOl-T-ABsKLoVg2eY81DMkwdWkevAnjXj2QnLXI,532
79
- dstack/_internal/core/backends/base/offers.py,sha256=87I7f2Perkc3Gt9tJ4stWvPAP3ZklJNk8XHKAXYaVmg,7555
79
+ dstack/_internal/core/backends/base/offers.py,sha256=5dfQbcXsqjOdGckPooH_x1B78CfAdsqXvMDlIIqF5ik,7617
80
80
  dstack/_internal/core/backends/cloudrift/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
81
81
  dstack/_internal/core/backends/cloudrift/api_client.py,sha256=mI3_ttwujfSunTiTIelnc1XaLBlfxsKsacrlyB12f8c,8178
82
82
  dstack/_internal/core/backends/cloudrift/backend.py,sha256=Jz3nIQsa3TnMISVXK6EU43O0B7FgIMxwwaEBmd_s5BY,596
@@ -109,9 +109,9 @@ dstack/_internal/core/backends/dstack/models.py,sha256=Jbe0Syez43N5i97TlIc8l-5Vn
109
109
  dstack/_internal/core/backends/gcp/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
110
110
  dstack/_internal/core/backends/gcp/auth.py,sha256=VWCn34hapaZ3E0OHCoiAVL97o3s64RF9w85CZ6xdtmk,2235
111
111
  dstack/_internal/core/backends/gcp/backend.py,sha256=OvTv1c7j4LTPCIEtkwD3-q6Eo1QET8xlM8CzbY0hLmI,572
112
- dstack/_internal/core/backends/gcp/compute.py,sha256=ebax_Yqs0zlDYeYwRtz1tlL0sNZKWM0ieyQNFBA7nbg,51364
112
+ dstack/_internal/core/backends/gcp/compute.py,sha256=rfIGOmaauRXTU-tjc7Krv96Dugq_etHIcuocgEaAx48,51783
113
113
  dstack/_internal/core/backends/gcp/configurator.py,sha256=pA3o5--gKBMLXvlAUIgBL30ayeUBWsLS-xqMljIlzAM,6887
114
- dstack/_internal/core/backends/gcp/models.py,sha256=1g3U1zktb6RkWag7EPcAoSZejkf5lUrMlpos0_WUEus,5489
114
+ dstack/_internal/core/backends/gcp/models.py,sha256=Vcut665e2ErYvnbIrTujA0m_556PxUbbP_ta1Yso6Qo,5555
115
115
  dstack/_internal/core/backends/gcp/resources.py,sha256=a_WlJkDIIlyKd9eSbeHNaAwAo1ZxLHkDUYn4-K_3u_Q,21077
116
116
  dstack/_internal/core/backends/gcp/features/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
117
117
  dstack/_internal/core/backends/gcp/features/tcpx.py,sha256=8bDR5kwF5qke5EWNdBscdbZQnC7oVXKSls3WPcoXgZI,2902
@@ -155,7 +155,7 @@ dstack/_internal/core/backends/oci/resources.py,sha256=-47u2vWvRnpNQmgz3A12vu1hS
155
155
  dstack/_internal/core/backends/runpod/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
156
156
  dstack/_internal/core/backends/runpod/api_client.py,sha256=Oet7CwQTu3sE57unqh-JvuMCBDEDPruAbGB4GyM0dM4,13427
157
157
  dstack/_internal/core/backends/runpod/backend.py,sha256=GcLbySsGY29ZGHXSqTXCxUUoTK9pxVScKly0_fkNr8c,566
158
- dstack/_internal/core/backends/runpod/compute.py,sha256=0KwqTfvjNxZXkHS_Y8fYDMHMzL_vo-bxXg00djUIJRo,11097
158
+ dstack/_internal/core/backends/runpod/compute.py,sha256=p96oc0Mg0Zjtfj25dVzattHBKtbYuMTeWMpYodAg4rg,11264
159
159
  dstack/_internal/core/backends/runpod/configurator.py,sha256=ZcDKN5ulmFMjSy9TlnV-2qxqPwTZUpIwfVwtShZL5fU,2242
160
160
  dstack/_internal/core/backends/runpod/models.py,sha256=W3nO4sjvvWtfKYDZDVJ8oBSsgeGdSR-Z_PD7OpfDBgY,1466
161
161
  dstack/_internal/core/backends/template/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -182,7 +182,7 @@ dstack/_internal/core/compatibility/fleets.py,sha256=jg42A7OmprqATKKt6JpLL1qOQSZ
182
182
  dstack/_internal/core/compatibility/gateways.py,sha256=4h_lfpN9KJFyLTFexq-wlu74Rwpk0anV67v38aJ-SnI,1463
183
183
  dstack/_internal/core/compatibility/gpus.py,sha256=myWVUjaK2S1QuYgRZyMtD8-DPKQTjadSbsnECtfoHHs,575
184
184
  dstack/_internal/core/compatibility/logs.py,sha256=keXt3OFKR0CjD_XMsetzRu8yQGCz7CWBwycuP267L_Q,629
185
- dstack/_internal/core/compatibility/runs.py,sha256=pT5RxheOzJJXFpJM1th-ku9-inj3McMBcdEHxcMBp9U,9357
185
+ dstack/_internal/core/compatibility/runs.py,sha256=i2vJwTGuT1GZ2pYzUnM6DpewsjqbArd3zsdp-x_VGGQ,10453
186
186
  dstack/_internal/core/compatibility/volumes.py,sha256=ofjpVusuc-pq285bGrIh8PAqu0QlAd6NQgU3gfJQIc0,1546
187
187
  dstack/_internal/core/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
188
188
  dstack/_internal/core/models/common.py,sha256=QKdZM7L2NepzOPavkkI_q3g6WYCauMTbtZSZwWZVYHE,4704
@@ -193,14 +193,14 @@ dstack/_internal/core/models/files.py,sha256=CI1AQN07ACot_6RVkG7qLml07Ro0co2hGsA
193
193
  dstack/_internal/core/models/fleets.py,sha256=Ux-RSdoJUFF4lSDPH70MJKoav_xYv0w9Ou_BwOJevq0,15215
194
194
  dstack/_internal/core/models/gateways.py,sha256=_O8EWwHWLdgNoWY4P4u71KM-uEr5DDp42LXfyv1qMDI,4054
195
195
  dstack/_internal/core/models/health.py,sha256=Q0Z5pYbW-rD5wLn3-EDre2Q7X6tX7DFaglKz5SDv18U,570
196
- dstack/_internal/core/models/instances.py,sha256=Gpv46fu3uWO-3f8w1A6rBzU5dYhmO_wWh9s8fvnd9iw,6872
196
+ dstack/_internal/core/models/instances.py,sha256=nITxuRsT3OqPMi1HFN9Bq0rTFwsIJPXbRgxhtfvSeQM,6915
197
197
  dstack/_internal/core/models/logs.py,sha256=VOsgEsvUIRNNHivD6OZnPZNC52ioqafv7ccdnFQ1YI8,529
198
198
  dstack/_internal/core/models/metrics.py,sha256=Xb8hCXUL-ncQ3PMsErIUAJTe9gwh5jyrQ4UQoZbibsc,269
199
199
  dstack/_internal/core/models/placement.py,sha256=WJVq5ENJykyRarQzL2EeYQag_9_jV7VSAtR_xoFvPVM,720
200
200
  dstack/_internal/core/models/profiles.py,sha256=vzGQllBGepTcFotgpot6OksyBIM03IJWtW3kZEfkro4,14524
201
201
  dstack/_internal/core/models/projects.py,sha256=hOZoL85q-873vT_Aw7FhzpS6DGVt0Y3yT8kpElrLFto,833
202
202
  dstack/_internal/core/models/resources.py,sha256=-dLupzud5BSqxNABBjLVYTCKekbr9_mhaNGD1ZWBjgM,14544
203
- dstack/_internal/core/models/runs.py,sha256=UZd2iJNgeRBrX6eHleHXjgpEzvCCxzfZKECAA5M_Vrk,22688
203
+ dstack/_internal/core/models/runs.py,sha256=M5IG0SsMgAzZpFamHjgV1Fit4wwxA8mPExW8koCUkeo,22737
204
204
  dstack/_internal/core/models/secrets.py,sha256=5T4B4eCeZmVQ8t22qYYlm4NUyX7VloiXCJuyDfE92QA,413
205
205
  dstack/_internal/core/models/server.py,sha256=Hkc1v2s3KOiwslsWVmhUOAzcSeREoG-HD1SzSX9WUGg,152
206
206
  dstack/_internal/core/models/services.py,sha256=2Hpi7j0Q1shaf_0wd0C0044AJAmuYi-D3qx3PH849oI,3076
@@ -224,6 +224,7 @@ dstack/_internal/core/services/configs/__init__.py,sha256=FW_A4TprMuY1PA_nOoAJNQ
224
224
  dstack/_internal/core/services/ssh/__init__.py,sha256=UhgC3Lv3CPSGqSPEQZIKOfLKUlCFnaB0uqPQhfKCFt0,878
225
225
  dstack/_internal/core/services/ssh/attach.py,sha256=6YZ_HaimKrjdLzcDLksGi0_9rlVyLeBgPmmWHC7dYxo,9096
226
226
  dstack/_internal/core/services/ssh/client.py,sha256=FUg74jNOagYR3OKuWMBwNgJWIDwHfYrIMSER8xn92D8,4102
227
+ dstack/_internal/core/services/ssh/key_manager.py,sha256=koinlhUAtFyhmDBLGwD9Z36HQzQtzp-GeXvPhefq33c,1855
227
228
  dstack/_internal/core/services/ssh/ports.py,sha256=m5YofoHBo2jhurfUi5UEpdrH0IWjgJ5XKRdG-15bIhA,2914
228
229
  dstack/_internal/core/services/ssh/tunnel.py,sha256=NLnb4YyzvqmKdNvSlj9IV2I9QdrPyGdw-Oac6EeVjTk,11767
229
230
  dstack/_internal/proxy/__init__.py,sha256=xSEZgET1qgOhB3VASyP2oyTU93WUnMVCJ2wPZYJ4Di0,345
@@ -284,7 +285,7 @@ dstack/_internal/server/app.py,sha256=BdjpR_XsTMkNey85ZwTjKd9_KKbtlePnIqy7QQDQdq
284
285
  dstack/_internal/server/db.py,sha256=NY0-K_7ok2OYLtPMeZ4EHlHK5N2a77uj4aJCVgWO2qE,3245
285
286
  dstack/_internal/server/deps.py,sha256=31e8SU_ogPJWHIDLkgl7cuC_5V91xbJoLyAj17VanfM,670
286
287
  dstack/_internal/server/main.py,sha256=kztKhCYNoHSDyJJQScWfZXE0naNleJOCQULW6dd8SGw,109
287
- dstack/_internal/server/models.py,sha256=SXqbr4TRmGbr5WDR-MRza-sxkTvDnfh4i2uTg2y_Pcs,34373
288
+ dstack/_internal/server/models.py,sha256=Yre5SAgTZK58vmP49-TqIfeF31ZTNy5SCJJO8t-Ya3s,34566
288
289
  dstack/_internal/server/settings.py,sha256=7SRzSlTnUPNNjlZH-vpgwbwj95gI-LLtQite8LQnaTU,7418
289
290
  dstack/_internal/server/background/__init__.py,sha256=QftEjgQZffu83sY-F0WL65vRp28FbBEtezfowQYcTv4,5606
290
291
  dstack/_internal/server/background/tasks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -395,14 +396,14 @@ dstack/_internal/server/routers/gateways.py,sha256=ZZ77Qjv4sHVfsu63RLWf4mKRRSrdJ
395
396
  dstack/_internal/server/routers/gpus.py,sha256=1BUiV9A80-QralBWSzWiN6le3ywrbZ3uMjj7cgo8IYY,964
396
397
  dstack/_internal/server/routers/instances.py,sha256=VwhQ7vANbcluhgq10pPxm2RcR1OlDqUX6rP_OAZ20xU,2710
397
398
  dstack/_internal/server/routers/logs.py,sha256=qvlS_8fqyJe-vOEt420xYj4nc9eMb9ngzclmSiXk7Zs,1233
398
- dstack/_internal/server/routers/metrics.py,sha256=iXLbcJuwdi5F-lfkPhl9RzvC2m8FSp1EqaOwa-rb6YY,2426
399
+ dstack/_internal/server/routers/metrics.py,sha256=Hoa_cKF2-b8XNCVPa92YkFnNZhz1KHcriu2PpxwWRoU,2558
399
400
  dstack/_internal/server/routers/projects.py,sha256=qTwISp2O5L3zoysPyikH_IIqZSTkriUFOvrQPP_PCsQ,4915
400
401
  dstack/_internal/server/routers/prometheus.py,sha256=INRxPLYVJ6CTm2AwtSJ1z455RiCOpPJ3rbXMKGonGm8,1109
401
402
  dstack/_internal/server/routers/repos.py,sha256=4pTInkm0XaOVUJ2pRnbc8LqTyACkE3w_BrB6icT7EUw,4039
402
403
  dstack/_internal/server/routers/runs.py,sha256=m_IQMCeqh5Tp3OP7ulaBb1IND8b-ixqbVNiHgZtXrDo,6121
403
404
  dstack/_internal/server/routers/secrets.py,sha256=wWYUQbYcfWenUVEA4qdb08J7_6H3zmW3AsTIg-UTJ4o,2566
404
405
  dstack/_internal/server/routers/server.py,sha256=MSOsOCyA0unv24nCs_OkJG_zHyuldQrONn2xaZjGOXo,474
405
- dstack/_internal/server/routers/users.py,sha256=AkpE5DZgk6uukhbtlQIj40Sg7_npD9HrMfU87SlMMsE,3935
406
+ dstack/_internal/server/routers/users.py,sha256=L3t6WWvcl6pd8EGC5P6gsZVTtygyEpxsIDfAOqCVhdo,4302
406
407
  dstack/_internal/server/routers/volumes.py,sha256=PHmayi432nUAdcOiGOu1j2bfbIxCFjc8u4XRTrBiHEI,3856
407
408
  dstack/_internal/server/schemas/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
408
409
  dstack/_internal/server/schemas/backends.py,sha256=KC6ZunAW71OCEIE_LnPO-wScJKVFXLgcVVocrLATMi0,365
@@ -434,7 +435,7 @@ dstack/_internal/server/services/instances.py,sha256=-3m2WOg0R5W2X0IcMivT5C6Qha6
434
435
  dstack/_internal/server/services/locking.py,sha256=k00cS2SYUVekUIorsi6l5ofL-Q-Bnc5BnRZ1FAB6dDk,5239
435
436
  dstack/_internal/server/services/logging.py,sha256=IPyRg2c3gls_6KEJxus3hfFG8pgI4LqHM5b9F4VTI9g,816
436
437
  dstack/_internal/server/services/metrics.py,sha256=jKLy1jSCVR_crqVu_CmsOMbvMkucWBandI0SS1LDeRQ,6896
437
- dstack/_internal/server/services/offers.py,sha256=5T-qm8oB_4tdecP6JV84MkjbkFrfdAYgGlbA8eXQGsg,8469
438
+ dstack/_internal/server/services/offers.py,sha256=rv3f66jXku5yXZbfBz645OyW66bNAcDsmVlMj1rYxPU,8510
438
439
  dstack/_internal/server/services/permissions.py,sha256=l7Ngdelmn65vjw13NcOdaC6lBYMRuSw6FbHzYwdK3nE,1005
439
440
  dstack/_internal/server/services/placement.py,sha256=U-7z4kJ6ZyrCXzkDychWoOhniz19ooFwiNI2InoTLls,2420
440
441
  dstack/_internal/server/services/plugins.py,sha256=aOlqfTUiU2aZ5G4DUW2rY4959PqS2r9imo5pfU3NUww,3851
@@ -442,10 +443,10 @@ dstack/_internal/server/services/probes.py,sha256=pdgtkOvBuvneUo4Gysg8_afibTf1wu
442
443
  dstack/_internal/server/services/projects.py,sha256=PZdMCi1PVu68c_rYfwJRk7hgM6ddkekxlG_IU_957QI,25276
443
444
  dstack/_internal/server/services/repos.py,sha256=ECl1cbpdzhTv1P3Y9IQmoWyHHF8iXFyL4s2drfwRDvg,9352
444
445
  dstack/_internal/server/services/resources.py,sha256=VRFOih_cMJdc0c2m9nSGsX8vWAJQV3M6N87aqS_JXfw,699
445
- dstack/_internal/server/services/runs.py,sha256=v4CwgaRd8AK4KJ0D4qcHC56FFsRHKvwVP7GHOunQ_dM,48088
446
+ dstack/_internal/server/services/runs.py,sha256=d19AJkmKjfVezNyEx79sHYeFMaTHqWQenuci9ZpjdJY,48266
446
447
  dstack/_internal/server/services/secrets.py,sha256=M7RS4X1-DIL0f7m6BBb3PhsrAbxwKUD3_pZEWRfR3sM,5567
447
448
  dstack/_internal/server/services/ssh.py,sha256=DT7U_8ON8o30-53WlJwjd5kVrKyt4KPgKeN63NW3P8U,2883
448
- dstack/_internal/server/services/users.py,sha256=CFPACnLatZnqVU8Gdj_fMpeF8LTHB_30rv-LhYlDWAk,8663
449
+ dstack/_internal/server/services/users.py,sha256=JhlgG4n2CU3cO7zAaA78YCTzb2nzE7GIBZgJ_eXLnOA,8649
449
450
  dstack/_internal/server/services/volumes.py,sha256=DBGIUsysAO7sQ6vb4mjhzO9XLdyQvtNujucxhGnkSsU,16682
450
451
  dstack/_internal/server/services/backends/__init__.py,sha256=xWHI-A24u9RE7H5I4A3e_JQyuQtp5pdKbU--ZyizrnU,13420
451
452
  dstack/_internal/server/services/backends/handlers.py,sha256=Rz4QjqmmDGDzn6QbwxlJvV5oC6pE4PZN3FX0DVqnBHc,3539
@@ -458,7 +459,7 @@ dstack/_internal/server/services/gateways/__init__.py,sha256=ULqgi5yDkTJhSa8qfrD
458
459
  dstack/_internal/server/services/gateways/client.py,sha256=Os6V1zS_fxmchmhyoIkoB4whsYmgm3c-XX54hoERO1k,7726
459
460
  dstack/_internal/server/services/gateways/connection.py,sha256=31qellW-zc-l8cxb8se6AshX5yS_HZT8Nlvxy9JkOXQ,5630
460
461
  dstack/_internal/server/services/gateways/pool.py,sha256=0LclTl1tyx-doS78LeaAKjr-SMp98zuwh5f9s06JSd0,1914
461
- dstack/_internal/server/services/jobs/__init__.py,sha256=qB5Y2DdpQkShfBUDIqHWJis_oA75e6jfHy7KgjwvLL0,28351
462
+ dstack/_internal/server/services/jobs/__init__.py,sha256=NGzjziUlIILbZuDyPlMYxMayGkdfW4tRDxBtPEGlmNU,28491
462
463
  dstack/_internal/server/services/jobs/configurators/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
463
464
  dstack/_internal/server/services/jobs/configurators/base.py,sha256=b-VI8bo5-glLR3ycio7OEC6ILTy6sap-bCH7N6Oq06w,15996
464
465
  dstack/_internal/server/services/jobs/configurators/dev.py,sha256=6dEbuRYr83XAmgie63uyq6jE0Er2Vd1kTZKPy8kpvY4,2635
@@ -521,11 +522,11 @@ dstack/_internal/server/statics/e467d7d60aae81ab198b.svg,sha256=_XHc9mfQZgGkcy4h
521
522
  dstack/_internal/server/statics/eb9b344b73818fe2b71a.png,sha256=2H14eOCQRyZhFGJ1Kn2LH1j70kTF1Qop4vH-tiKqyPI,85
522
523
  dstack/_internal/server/statics/f517dd626eb964120de0.png,sha256=4QQuNa8SqmcZ67HK6739OHCyjnAJseU1bkcn454KRQs,159
523
524
  dstack/_internal/server/statics/f958aecddee5d8e3222c.png,sha256=8CoZkVNgRfOAe62X1dU-AZDvwh_nESKaQblEmaX2Xrs,87
524
- dstack/_internal/server/statics/index.html,sha256=T9ZlkECfVpgoCT7hGM81NvPmAz32YSNSq2RfA2D5als,11155
525
+ dstack/_internal/server/statics/index.html,sha256=C32BsHh914F45DyJTQFyqimHuOtNzwlIgcHgzTzKAUg,11155
525
526
  dstack/_internal/server/statics/logo-notext.svg,sha256=Oth7XfcAeDJcaPdzNtDaqYuLU7mCB0JqNtxeyWb6Z3c,11231
526
527
  dstack/_internal/server/statics/main-720ce3a11140daa480cc.css,sha256=phgVgWaKKHEWgAux1if7DRn6sM_ykbdu9OPcuiflezg,1473211
527
- dstack/_internal/server/statics/main-97c7e184573ca23f9fe4.js,sha256=LdT0_PaR1s7SsP_0SIbzkaM42h4Cs_BHksQXiRq-4AQ,7111664
528
- dstack/_internal/server/statics/main-97c7e184573ca23f9fe4.js.map,sha256=-5MY6B04RIHgL-pufWYPqng9uYNyi_s64kRihkK6j6k,9461080
528
+ dstack/_internal/server/statics/main-e79754c136f1d8e4e7e6.js,sha256=bsms1CoIGR9qdGCGcJ1CqCdmFHPbjdB_mWjbWe-0i0I,7113855
529
+ dstack/_internal/server/statics/main-e79754c136f1d8e4e7e6.js.map,sha256=MFnr-QqmgFVQq5-8GN9t0uB_Yyzb9MLEH7gYG4LQgFc,9465506
529
530
  dstack/_internal/server/statics/manifest.json,sha256=430w2BoWVmYYVr14lDvUxx-ROPt3VjigzeMqfLeiSCM,340
530
531
  dstack/_internal/server/statics/robots.txt,sha256=kNJLw79pisHhc3OVAimMzKcq3x9WT6sF9IS4xI0crdI,67
531
532
  dstack/_internal/server/statics/assets/android-chrome-144x144.png,sha256=tB3V-95O-VVEoawN5V1XFoMQRSK0I6gthraV8bATGaw,23414
@@ -603,7 +604,7 @@ dstack/_internal/server/statics/static/media/logo.f602feeb138844eda97c8cb6414614
603
604
  dstack/_internal/server/statics/static/media/okta.12f178e6873a1100965f2a4dbd18fcec.svg,sha256=KqFI05gQM135zC1plF1WBRF2F7CyKL7km97WKsZjAHI,319
604
605
  dstack/_internal/server/statics/static/media/theme.3994c817bb7dda191c1c9640dee0bf42.svg,sha256=ZxFFBVZWuRLqmWH4zhwGLNtKjOzHj-5MGJRunFAtu1I,561
605
606
  dstack/_internal/server/testing/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
606
- dstack/_internal/server/testing/common.py,sha256=QwlSJJEXEFRu_SoiiZ9S84jfT-vwy2OwXwAqOUq5NWU,36016
607
+ dstack/_internal/server/testing/common.py,sha256=NvtrwBsNbJD0cWLCyQvNbUHZmaIHSenwY0zpfA4CV5o,36181
607
608
  dstack/_internal/server/testing/conf.py,sha256=-zhujfFjTHNfQDOK-hBck32By11c_kC0OeinB3esQGg,1902
608
609
  dstack/_internal/server/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
609
610
  dstack/_internal/server/utils/common.py,sha256=PbjXtqYy1taKXpyG5ys8cIrz9MXqc9dBAsR_9D1brrk,1414
@@ -634,11 +635,11 @@ dstack/_internal/utils/tags.py,sha256=Gx4aZM85E_UUCGuFZbCEFxHB5DNgrtJP15_1tFFEd1
634
635
  dstack/_internal/utils/typing.py,sha256=tHrhtkr3G6jkk-_FZyobdjLYvP5_YIgXbKsN-13dfvg,386
635
636
  dstack/api/__init__.py,sha256=7qbG42qEHMyNDFRCz9FgfuimAKws3hV8eMXs6oRgh5c,1607
636
637
  dstack/api/utils.py,sha256=_la3CRk1vgrPGkInPI1SOr33e8Jvh8ziJC32fjvKnaU,4188
637
- dstack/api/_public/__init__.py,sha256=eb6mmLtoF-Zq-od0F1Nz3IsMQ6IHmZcv7lfvgyE8rho,3223
638
+ dstack/api/_public/__init__.py,sha256=TqSWVMoidDy1iL4OqF6mMIwhl55pHD2A5vJcV9O61S0,3227
638
639
  dstack/api/_public/backends.py,sha256=w_cIUVU3L1tN8VoPH6-ltq-oJewlfXWTiEFXfDvm-1Q,1056
639
640
  dstack/api/_public/repos.py,sha256=99tzFSFOQejLQIfMlzoGlR3ZzLRs42pIvpkzkgwkyhQ,7464
640
- dstack/api/_public/runs.py,sha256=z3dMCcN7Kpdk7lWjXF6PPkJWhGxLgYQ6WBKii0gIvt8,34784
641
- dstack/api/server/__init__.py,sha256=6hr2scrtZ1LsH_VQ7TRYlKoOykL1wsSnDb6ZzMZ1T_U,6712
641
+ dstack/api/_public/runs.py,sha256=KxEYnDGl_AuZUfaWWiberX_a72cAOp_Xwg3iX7wBjyU,34967
642
+ dstack/api/server/__init__.py,sha256=uiBK5vFnlPFBf5Dt15EBowhgnyMNg048zM-0Icewh2E,6831
642
643
  dstack/api/server/_backends.py,sha256=tSvJ4j-yp-S-4IYo7pKHluDaSsx6Xbwo08Ff6Do85fo,1639
643
644
  dstack/api/server/_files.py,sha256=iOBHm1CvJiG4TqNx3t5LYOf7w3jff9I15wxYpIAg-r4,780
644
645
  dstack/api/server/_fleets.py,sha256=6Duz5-SF1HI4qIkgdJr8OikzDosYtavJZOEyMwyDu_8,2882
@@ -663,8 +664,8 @@ dstack/plugins/builtin/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3
663
664
  dstack/plugins/builtin/rest_plugin/__init__.py,sha256=lgTsq8Z6Km2F2UhPRChVB4vDM5ZpWtdk1iB1aa20ypA,440
664
665
  dstack/plugins/builtin/rest_plugin/_models.py,sha256=9hgVuU6OGSxidar88XhQnNo9izYWeQvVH45ciErv-Es,1910
665
666
  dstack/plugins/builtin/rest_plugin/_plugin.py,sha256=h3r3Yc3h22i93fifPTgTm9Oojd1sN1O4DP7ZTV-kWpM,5386
666
- dstack-0.19.33.dist-info/METADATA,sha256=VjbOSIJ8_gtS7_uBG0v3m34l7ql13RGAoGgaSZ1Wuf0,20835
667
- dstack-0.19.33.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
668
- dstack-0.19.33.dist-info/entry_points.txt,sha256=GnLrMS8hx3rWAySQjA7tPNhtixV6a-brRkmal1PKoHc,58
669
- dstack-0.19.33.dist-info/licenses/LICENSE.md,sha256=qDABaRGjSKVOib1U8viw2P_96sIK7Puo426784oD9f8,15976
670
- dstack-0.19.33.dist-info/RECORD,,
667
+ dstack-0.19.34.dist-info/METADATA,sha256=5WStESpsR5DHP8bFfZxqKb3IVu9e9OTalq8ZE-K3epo,20835
668
+ dstack-0.19.34.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
669
+ dstack-0.19.34.dist-info/entry_points.txt,sha256=GnLrMS8hx3rWAySQjA7tPNhtixV6a-brRkmal1PKoHc,58
670
+ dstack-0.19.34.dist-info/licenses/LICENSE.md,sha256=qDABaRGjSKVOib1U8viw2P_96sIK7Puo426784oD9f8,15976
671
+ dstack-0.19.34.dist-info/RECORD,,